便携式加密算法
本文关键字:加密算法 便携式 | 更新日期: 2023-09-27 18:13:11
我需要实现一个新的或已经存在的加密算法,该算法使用另一个字符串作为密钥加密和解密字符串。问题是这个算法必须独立于使用它的计算机。
所以方法签名是:
public static string Encrypt(this string source, string key);
public static string Decrypt(this string source, string key);
我尝试了这些算法,但是它们不像我想的那样工作:
public static string Encrypt(this string source, string key)
{
if (String.IsNullOrEmpty(source) || String.IsNullOrEmpty(key))
throw new ArgumentException();
CspParameters cspp = new CspParameters { KeyContainerName = key };
using (var rsa = new RSACryptoServiceProvider(cspp) { PersistKeyInCsp = true })
return BitConverter.ToString(rsa.Encrypt(UTF8Encoding.UTF8.GetBytes(source), true));
}
public static string Decrypt(this string source, string key)
{
if (String.IsNullOrEmpty(source) || String.IsNullOrEmpty(key))
throw new ArgumentException();
try
{
CspParameters cspp = new CspParameters { KeyContainerName = key };
using (var rsa = new RSACryptoServiceProvider(cspp) { PersistKeyInCsp = true })
{
string[] decryptArray = source.Split(new char[] { '-' }, StringSplitOptions.None);
byte[] bytes = Array.ConvertAll<string, byte>(decryptArray, (s => Convert.ToByte(Byte.Parse(s, NumberStyles.HexNumber))));
return UTF8Encoding.UTF8.GetString(rsa.Decrypt(bytes, true));
}
}
catch
{ return null; }
}
我该怎么办?
KeyContainerName不是密钥。在上面的示例中,通过传递密钥作为存储名称,您将在每台机器上创建一个新的RSA密钥对,该密钥对具有您传入的密钥的存储名称(而不是像"MyRSAKeyPair"之类的存储名称)。这将意味着公钥和私钥将完全不同,您的例程似乎无法工作。
ALSO:您正在使用非对称加密,这有密钥长度的最大块大小限制。这意味着您要么需要创建一个分块机制(慢,因为非对称加密是昂贵的),要么使用像AES这样的对称机制,其中AES密钥在每个会话的基础上使用非对称加密(如RSA)发送。
您需要导出RSA公钥,然后将其导入远程计算机的密钥存储库。生成X509证书更容易(如果您只是在两台机器之间传输,您可以自签名,将其公共部分导出为. cer文件,然后您可以使用X509证书存储API来获取RSA提供者,这意味着您有一个很好的可传输密钥)。
public static RSACryptoServiceProvider GetRsaProviderFromCertificate()
{
X509Store store = new X509Store(StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
X509Certificate2Collection certCollection = (X509Certificate2Collection)store.Certificates;
foreach(X509Certificate2 cert in certCollection)
{
if (cert.SubjectName.Name.IndexOf("TheCertIWantToUse") > 0)
{
return cert.PrivateKey as RSACryptoServiceProvider;
}
}
我希望这足够明确…
如果你不想使用证书
// Export public key (on the encrypting end)
publicKey = rsaProvider.ToXmlString(false);
// Write public key to file
publicKeyFile = File.CreateText(publicKeyFileName);
publicKeyFile.Write(publicKey);
然后在另一台机器上
// Select target CSP
cspParams = new CspParameters();
cspParams.ProviderType = 1; // PROV_RSA_FULL
rsaProvider = new RSACryptoServiceProvider(cspParams);
// Read public key from file
publicKeyFile = File.OpenText(publicKeyFileName);
publicKeyText = publicKeyFile.ReadToEnd();
// Import public key
rsaProvider.FromXmlString(publicKeyText);