gpt4 book ai didi

c# - C#中用RSAServiceProvider加解密

转载 作者:太空狗 更新时间:2023-10-29 18:00:14 25 4
gpt4 key购买 nike

我正在尝试最基本的事情 - 使用公钥加密数据并使用私钥解密:

    X509Certificate2 cert = new X509Certificate2(@"c:\temp\CERT\mycert.pfx", "test1");

RSACryptoServiceProvider privateKey = cert.PrivateKey as RSACryptoServiceProvider;
RSACryptoServiceProvider publicKey = cert.PublicKey.Key as RSACryptoServiceProvider;

UnicodeEncoding bytConvertor = new UnicodeEncoding();
byte[] plainData = bytConvertor.GetBytes("Sample data");

byte[] enData = publicKey.Encrypt(plainData, true);
Console.WriteLine("Encrypted Output: {0}", bytConvertor.GetString(enData));

byte[] deData = privateKey.Decrypt(enData, true);
Console.WriteLine("Decrypted Output: {0}", bytConvertor.GetString(deData));

但倒数第二行 privateKey.Decrypt(...) 抛出以下异常:

System.Security.Cryptography.CryptographicException was unhandled
Message=Bad Key.

Source=mscorlib   StackTrace:
at System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr)
at System.Security.Cryptography.RSACryptoServiceProvider.DecryptKey(SafeKeyHandle
pKeyContext, Byte[] pbEncryptedKey, Int32 cbEncryptedKey, Boolean
fOAEP, ObjectHandleOnStack ohRetDecryptedKey)
at System.Security.Cryptography.RSACryptoServiceProvider.Decrypt(Byte[]
rgb, Boolean fOAEP)
at ConsoleApplication4.Program.Main(String[] args) in `c:\users\kazia\documents\visual studio`
`2010\Projects\ConsoleApplication4\Program.cs`:line 44 ...

InnerException:

我一定遗漏了一些明显的东西。使用.NET 在两端(公共(public)和私有(private))使用 RSA 加密的标准方法是什么?任何帮助将不胜感激。

谢谢!

最佳答案

在这里找到答案:

http://msdn.microsoft.com/en-us/library/ms148409.aspx

很好的例子:

using System;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.IO;
using System.Text;

// To run this sample use the Certificate Creation Tool (Makecert.exe) to generate a test X.509 certificate and
// place it in the local user store.
// To generate an exchange key and make the key exportable run the following command from a Visual Studio command prompt:

//makecert -r -pe -n "CN=CERT_SIGN_TEST_CERT" -b 01/01/2010 -e 01/01/2012 -sky exchange -ss my
namespace X509CertEncrypt
{
class Program
{

// Path variables for source, encryption, and
// decryption folders. Must end with a backslash.
private static string encrFolder = @"C:\Encrypt\";
private static string decrFolder = @"C:\Decrypt\";
private static string originalFile = "TestData.txt";
private static string encryptedFile = "TestData.enc";

static void Main(string[] args)
{

// Create an input file with test data.
StreamWriter sw = File.CreateText(originalFile);
sw.WriteLine("Test data to be encrypted");
sw.Close();

// Get the certifcate to use to encrypt the key.
X509Certificate2 cert = GetCertificateFromStore("CN=CERT_SIGN_TEST_CERT");
if (cert == null)
{
Console.WriteLine("Certificatge 'CN=CERT_SIGN_TEST_CERT' not found.");
Console.ReadLine();
}


// Encrypt the file using the public key from the certificate.
EncryptFile(originalFile, (RSACryptoServiceProvider)cert.PublicKey.Key);

// Decrypt the file using the private key from the certificate.
DecryptFile(encryptedFile, (RSACryptoServiceProvider)cert.PrivateKey);

//Display the original data and the decrypted data.
Console.WriteLine("Original: {0}", File.ReadAllText(originalFile));
Console.WriteLine("Round Trip: {0}", File.ReadAllText(decrFolder + originalFile));
Console.WriteLine("Press the Enter key to exit.");
Console.ReadLine();
}
private static X509Certificate2 GetCertificateFromStore(string certName)
{

// Get the certificate store for the current user.
X509Store store = new X509Store(StoreLocation.CurrentUser);
try
{
store.Open(OpenFlags.ReadOnly);

// Place all certificates in an X509Certificate2Collection object.
X509Certificate2Collection certCollection = store.Certificates;
// If using a certificate with a trusted root you do not need to FindByTimeValid, instead:
// currentCerts.Find(X509FindType.FindBySubjectDistinguishedName, certName, true);
X509Certificate2Collection currentCerts = certCollection.Find(X509FindType.FindByTimeValid, DateTime.Now, false);
X509Certificate2Collection signingCert = currentCerts.Find(X509FindType.FindBySubjectDistinguishedName, certName, false);
if (signingCert.Count == 0)
return null;
// Return the first certificate in the collection, has the right name and is current.
return signingCert[0];
}
finally
{
store.Close();
}

}

// Encrypt a file using a public key.
private static void EncryptFile(string inFile, RSACryptoServiceProvider rsaPublicKey)
{
using (AesManaged aesManaged = new AesManaged())
{
// Create instance of AesManaged for
// symetric encryption of the data.
aesManaged.KeySize = 256;
aesManaged.BlockSize = 128;
aesManaged.Mode = CipherMode.CBC;
using (ICryptoTransform transform = aesManaged.CreateEncryptor())
{
RSAPKCS1KeyExchangeFormatter keyFormatter = new RSAPKCS1KeyExchangeFormatter(rsaPublicKey);
byte[] keyEncrypted = keyFormatter.CreateKeyExchange(aesManaged.Key, aesManaged.GetType());

// Create byte arrays to contain
// the length values of the key and IV.
byte[] LenK = new byte[4];
byte[] LenIV = new byte[4];

int lKey = keyEncrypted.Length;
LenK = BitConverter.GetBytes(lKey);
int lIV = aesManaged.IV.Length;
LenIV = BitConverter.GetBytes(lIV);

// Write the following to the FileStream
// for the encrypted file (outFs):
// - length of the key
// - length of the IV
// - ecrypted key
// - the IV
// - the encrypted cipher content

int startFileName = inFile.LastIndexOf("\\") + 1;
// Change the file's extension to ".enc"
string outFile = encrFolder + inFile.Substring(startFileName, inFile.LastIndexOf(".") - startFileName) + ".enc";
Directory.CreateDirectory(encrFolder);

using (FileStream outFs = new FileStream(outFile, FileMode.Create))
{

outFs.Write(LenK, 0, 4);
outFs.Write(LenIV, 0, 4);
outFs.Write(keyEncrypted, 0, lKey);
outFs.Write(aesManaged.IV, 0, lIV);

// Now write the cipher text using
// a CryptoStream for encrypting.
using (CryptoStream outStreamEncrypted = new CryptoStream(outFs, transform, CryptoStreamMode.Write))
{

// By encrypting a chunk at
// a time, you can save memory
// and accommodate large files.
int count = 0;
int offset = 0;

// blockSizeBytes can be any arbitrary size.
int blockSizeBytes = aesManaged.BlockSize / 8;
byte[] data = new byte[blockSizeBytes];
int bytesRead = 0;

using (FileStream inFs = new FileStream(inFile, FileMode.Open))
{
do
{
count = inFs.Read(data, 0, blockSizeBytes);
offset += count;
outStreamEncrypted.Write(data, 0, count);
bytesRead += blockSizeBytes;
}
while (count > 0);
inFs.Close();
}
outStreamEncrypted.FlushFinalBlock();
outStreamEncrypted.Close();
}
outFs.Close();
}
}
}
}


// Decrypt a file using a private key.
private static void DecryptFile(string inFile, RSACryptoServiceProvider rsaPrivateKey)
{

// Create instance of AesManaged for
// symetric decryption of the data.
using (AesManaged aesManaged = new AesManaged())
{
aesManaged.KeySize = 256;
aesManaged.BlockSize = 128;
aesManaged.Mode = CipherMode.CBC;

// Create byte arrays to get the length of
// the encrypted key and IV.
// These values were stored as 4 bytes each
// at the beginning of the encrypted package.
byte[] LenK = new byte[4];
byte[] LenIV = new byte[4];

// Consruct the file name for the decrypted file.
string outFile = decrFolder + inFile.Substring(0, inFile.LastIndexOf(".")) + ".txt";

// Use FileStream objects to read the encrypted
// file (inFs) and save the decrypted file (outFs).
using (FileStream inFs = new FileStream(encrFolder + inFile, FileMode.Open))
{

inFs.Seek(0, SeekOrigin.Begin);
inFs.Seek(0, SeekOrigin.Begin);
inFs.Read(LenK, 0, 3);
inFs.Seek(4, SeekOrigin.Begin);
inFs.Read(LenIV, 0, 3);

// Convert the lengths to integer values.
int lenK = BitConverter.ToInt32(LenK, 0);
int lenIV = BitConverter.ToInt32(LenIV, 0);

// Determine the start postition of
// the ciphter text (startC)
// and its length(lenC).
int startC = lenK + lenIV + 8;
int lenC = (int)inFs.Length - startC;

// Create the byte arrays for
// the encrypted AesManaged key,
// the IV, and the cipher text.
byte[] KeyEncrypted = new byte[lenK];
byte[] IV = new byte[lenIV];

// Extract the key and IV
// starting from index 8
// after the length values.
inFs.Seek(8, SeekOrigin.Begin);
inFs.Read(KeyEncrypted, 0, lenK);
inFs.Seek(8 + lenK, SeekOrigin.Begin);
inFs.Read(IV, 0, lenIV);
Directory.CreateDirectory(decrFolder);
// Use RSACryptoServiceProvider
// to decrypt the AesManaged key.
byte[] KeyDecrypted = rsaPrivateKey.Decrypt(KeyEncrypted, false);

// Decrypt the key.
using (ICryptoTransform transform = aesManaged.CreateDecryptor(KeyDecrypted, IV))
{

// Decrypt the cipher text from
// from the FileSteam of the encrypted
// file (inFs) into the FileStream
// for the decrypted file (outFs).
using (FileStream outFs = new FileStream(outFile, FileMode.Create))
{

int count = 0;
int offset = 0;

int blockSizeBytes = aesManaged.BlockSize / 8;
byte[] data = new byte[blockSizeBytes];

// By decrypting a chunk a time,
// you can save memory and
// accommodate large files.

// Start at the beginning
// of the cipher text.
inFs.Seek(startC, SeekOrigin.Begin);
using (CryptoStream outStreamDecrypted = new CryptoStream(outFs, transform, CryptoStreamMode.Write))
{
do
{
count = inFs.Read(data, 0, blockSizeBytes);
offset += count;
outStreamDecrypted.Write(data, 0, count);

}
while (count > 0);

outStreamDecrypted.FlushFinalBlock();
outStreamDecrypted.Close();
}
outFs.Close();
}
inFs.Close();
}

}

}
}

}
}

关于c# - C#中用RSAServiceProvider加解密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9257714/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com