便携式加密算法

本文关键字:加密算法 便携式 | 更新日期: 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);