System.Security.Cryptography与PCLCrypto

时间:2015-08-19 19:51:24

标签: c# encryption portable-class-library pcl-crypto

我们正在制作系统中的许多共享功能并将其移植到PCL库。我在使用PCLCrypto时遇到了问题。我正在我们的数据库中获取一些现有数据,并尝试使用相同的算法对其进行解密。我得到了值,但最后有16个额外的字节只是垃圾。

参见下面的代码: 使用System.Security.Cryptography

的旧算法
public static string SymmetricEncrypt(this string plaintext, string key, SymmetricAlgorithm algorithm)
{
    byte[] keyBuffer = Convert.FromBase64String(key.Hash(HashAlgorithm.MD5));
    byte[] plainTextBuffer = Encoding.UTF8.GetBytes(plaintext);

   var symmetricAlgorithm = new AesCryptoServiceProvider();
    symmetricAlgorithm.Key = keyBuffer;
    symmetricAlgorithm.Mode = CipherMode.ECB;

    var encryptor = symmetricAlgorithm.CreateEncryptor();
    byte[] cipherBuffer = encryptor.TransformFinalBlock(plainTextBuffer, 0, plainTextBuffer.Length);
    symmetricAlgorithm.Clear();

    return Convert.ToBase64String(cipherBuffer);
}


 public static string SymmetricDecrypt(this string cipherText, string key, SymmetricAlgorithm algorithm)
    {
        byte[] keyBuffer = Convert.FromBase64String(key.Hash(HashAlgorithm.MD5));
        byte[] cipherTextBuffer = Convert.FromBase64String(cipherText);
        var symmetricAlgorithm = new AesCryptoServiceProvider();
        symmetricAlgorithm.Key = keyBuffer;
        symmetricAlgorithm.Mode = CipherMode.ECB;

        var decryptor = symmetricAlgorithm.CreateDecryptor();
        byte[] plainTextBuffer = decryptor.TransformFinalBlock(cipherTextBuffer, 0, cipherTextBuffer.Length);
        symmetricAlgorithm.Clear();

        return Encoding.Default.GetString(plainTextBuffer);
    }

使用PCLCrypto进行解密

public static string SymmetricDecrypt(this string cipherText, string key, SymmetricAlgorithm algorithm) {
    byte[] keyBuffer = Convert.FromBase64String(key.Hash(HashAlgorithm.MD5));
    byte[] cipherTextBuffer = Convert.FromBase64String(cipherText);

    ISymmetricKeyAlgorithmProvider symmetricAlgorithm = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(PCLCrypto.SymmetricAlgorithm.AesEcb);

    var symmetricKey = symmetricAlgorithm.CreateSymmetricKey(keyBuffer);
    var decryptor = WinRTCrypto.CryptographicEngine.CreateDecryptor(symmetricKey);
   byte[] plainTextBuffer = decryptor.TransformFinalBlock(cipherTextBuffer, 0, cipherTextBuffer.Length);
    return UTF8Encoding.UTF8.GetString(plainTextBuffer, 0, plainTextBuffer.Length);
}

使用旧版本:plainTextBuffer是16个字节,新版本是32个字节。

帮助!

1 个答案:

答案 0 :(得分:4)

这听起来像填充问题。

查看.NET中基类SymmetricAlgorithm的源代码,它是AesCryptoServiceProvider的基础,默认填充是PaddingMode.PKCS7。你似乎没有定义填充模式,所以我认为默认仍然适用。

虽然之前我还没有使用过PCLCrypto库,但快速浏览一下github有几种AesEcb算法:AesEcb和AesEcbPkcs7。 AesEcb名称中缺少填充模式意味着它没有填充(因此没有删除任何填充),这相当于.NET库中的PaddingMode.None。

尝试在PCLCrypto中使用PCLCrypto.SymmetricAlgorithm.AesEcbPkcs7算法,看看是否删除了在输出结尾处看到的填充。

<强> 更新

我刚测试了这个,它似乎正常工作并删除了你会看到的填充:

public static string SymmetricDecrypt(this string cipherText, string key, SymmetricAlgorithm algorithm) {
    byte[] keyBuffer = Convert.FromBase64String(key.Hash(HashAlgorithm.MD5));
    byte[] cipherTextBuffer = Convert.FromBase64String(cipherText);

    ISymmetricKeyAlgorithmProvider symmetricAlgorithm = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(PCLCrypto.SymmetricAlgorithm.AesEcbPkcs7);

    var symmetricKey = symmetricAlgorithm.CreateSymmetricKey(keyBuffer);
    var decryptor = WinRTCrypto.CryptographicEngine.CreateDecryptor(symmetricKey);
   byte[] plainTextBuffer = decryptor.TransformFinalBlock(cipherTextBuffer, 0, cipherTextBuffer.Length);
    return UTF8Encoding.UTF8.GetString(plainTextBuffer, 0, plainTextBuffer.Length);
}

唯一的变化是将算法从PCLCrypto.SymmetricAlgorithm.AesEcb更改为PCLCrypto.SymmetricAlgorithm.AesEcbPkcs7