2015-10-30 106 views
1

我有用AesCryptoServiceProvider加密的磁盘上的文件。 我需要将代码转换为PCL(它没有类AesCryptoServiceProvider)。所以我想用Bouncy Castle(https://www.nuget.org/packages/Portable.BouncyCastle/)来读取和保存文件而不改变加密。并防止需要转换所有文件。将AesCryptoServiceProvider的加密转换为BouncyCastle

Key是32个字节长。 IV长16字节。

下面是原来的代码:

private static byte[] Encrypt(string plainText, byte[] Key, byte[] IV) 
{ 
    using (AesCryptoServiceProvider aesAlg = new AesCryptoServiceProvider()) 
    { 
     aesAlg.Key = Key; 
     aesAlg.IV = IV; 

     ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV); 
     using (MemoryStream outputStream = new MemoryStream()) 
     { 
      using (CryptoStream csEncrypt = new CryptoStream(outputStream, encryptor, CryptoStreamMode.Write)) 
      { 
       using (StreamWriter swEncrypt = new StreamWriter(csEncrypt)) 
       { 
        swEncrypt.Write(plainText); 
       } 
      } 

      return outputStream.ToArray(); 
     } 
    } 
} 

AesCryptoServiceProvider默认模式是CBCPKCS7类型的填充,然后我试图与类CbcBlockCipherPkcs7Padding。这是我最后一次尝试:

private static byte[] Encrypt(byte[] input, byte[] key, byte[] IV) 
{ 
    var keyParameter = new KeyParameter(key); 
    var parameters = new ParametersWithIV(keyParameter, IV); 

    var cipher = new PaddedBufferedBlockCipher(new CbcBlockCipher(new AesEngine()), new Pkcs7Padding()); 

    cipher.Init(true, parameters); 

    var rsl = new byte[cipher.GetOutputSize(input.Length)]; 
    var outOff = cipher.ProcessBytes(input, 0, input.Length, rsl, 0); 

    cipher.DoFinal(rsl, outOff); 
    return rsl; 
} 

原来的结果为文本“测试”是8jykPv2OSILKjJwvgLRr1w==,但随着新的代码是BaYeiuWSnRiHXBpwt19Dag==

那我想念什么?

感谢您的帮助!

更新#1: 这里是键和值IV:

private static byte[] KEY = {98, 193, 95, 78, 211, 151, 118, 57, 179, 5, 85, 181, 133, 20, 94, 101, 184, 175, 94, 164, 150, 119, 75, 207, 189, 178, 21, 213, 13, 217, 174, 44}; 
private static byte[] IV = {1, 199, 179, 189, 160, 220, 229, 238, 179, 14, 255, 147, 187, 49, 179, 134 }; 

更新#2: 对于充气城堡,将我plainTextinput这一行:

var input = Encoding.Unicode.GetBytes(plainText); 

差异来自那里...

+1

什么是关键和IV? –

+0

@JamesKPolk:增值! – Kipotlov

+0

您能借此机会通过安全加密取代加密吗?由于它使用了一个常量IV(完全忽略了IV的要点)并且缺少一个MAC,所以现有的比较弱。 – CodesInChaos

回答

0

调用使用BouncyCastle的加密()方法之前,我将我串Encoding.Unicode.GetBytes(plainText);代替Encoding.UTF8.GetBytes(plainText);

用此修复程序,无论方法给出相同的结果!

0

问题是编码的Streamwriter。写入CryptoStream的时候它带来的相同的结果:

[TestMethod] 
    public void windows() 
    { 

     byte[] KEY = { 98, 193, 95, 78, 211, 151, 118, 57, 179, 5, 85, 181, 133, 20, 94, 101, 184, 175, 94, 164, 150, 119, 75, 207, 189, 178, 21, 213, 13, 217, 174, 44 }; 
     byte[] IV = { 1, 199, 179, 189, 160, 220, 229, 238, 179, 14, 255, 147, 187, 49, 179, 134 }; 

     byte[] input = System.Text.Encoding.UTF8.GetBytes("test"); 

     string win = Convert.ToBase64String(Encrypt_win(input, KEY, IV)); 

     string bc = Convert.ToBase64String(Encrypt_bc(input, KEY, IV)); 



     Assert.AreEqual(win, "8jykPv2OSILKjJwvgLRr1w=="); 
     Assert.AreEqual(bc, "8jykPv2OSILKjJwvgLRr1w=="); 

    } 


    //private static byte[] Encrypt(string plainText, byte[] Key, byte[] IV) 
    private static byte[] Encrypt_win(byte[] input, byte[] Key, byte[] IV) 
    { 
     using (AesCryptoServiceProvider aesAlg = new AesCryptoServiceProvider()) 
     { 
      aesAlg.Key = Key; 
      aesAlg.IV = IV; 


      ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV); 
      using (MemoryStream outputStream = new MemoryStream()) 
      { 
       using (CryptoStream csEncrypt = new CryptoStream(outputStream, encryptor, CryptoStreamMode.Write)) 
       { 
        csEncrypt.Write(input, 0, input.Length); 

        /* 
        using (StreamWriter swEncrypt = new StreamWriter(csEncrypt)) 
        { 
         //swEncrypt.Write(plainText); 
         swEncrypt.Write(input); 
        } 
        */ 
       } 

       return outputStream.ToArray(); 
      } 
     } 
    } 



    private static byte[] Encrypt_bc(byte[] input, byte[] key, byte[] IV) 
    { 
     var keyParameter = new KeyParameter(key); 
     var parameters = new ParametersWithIV(keyParameter, IV); 

     var cipher = new PaddedBufferedBlockCipher(new CbcBlockCipher(new AesEngine()), new Pkcs7Padding()); 

     cipher.Init(true, parameters); 

     var rsl = new byte[cipher.GetOutputSize(input.Length)]; 
     var outOff = cipher.ProcessBytes(input, 0, input.Length, rsl, 0); 

     cipher.DoFinal(rsl, outOff); 
     return rsl; 
    } 
+0

感谢您的回答。问题不在于StreamWriter。但你的回答帮助我发现问题!我用'Encoding.Unicode.GetBytes(plainText);'而不是'Encoding.UTF8.GetBytes(plainText);'来转换我的字符串;'' – Kipotlov