2017-10-15 97 views
0

我必須在我們的Xamarin PCL項目中使用Aes加密。我們的項目使用可移植框架而不是標準,所以我不能使用新的內置類。我試圖改用.NET標準,但最終出現了無數的錯誤,由於我以前從未使用它,我想我現在可能不應該做出這樣的改變。Xamarin中的AesCryptoServiceProvider

我認爲這可以使用PCLCrypto軟件包來完成,但一直未能得到它的工作。

我們目前支持iOS和Android。

我想弄清楚如何從我們的服務器端轉換下面的代碼。

private static readonly byte[] CipherKey = ConvertHexStringToByteArray("some key"); 
static public string EncryptString(string originalPayload) 
    { 
     return Encrypt(originalPayload, CipherKey); 
    } 

    static private string Encrypt(string originalPayload, byte[] privateKey) 
    { 
     string encryptedPayload = ""; 

     using (var aes = new AesCryptoServiceProvider() 
     { 
      Key = privateKey, 
      Mode = CipherMode.CBC, 
      Padding = PaddingMode.PKCS7 
     }) 
     { 

      var input = Encoding.UTF8.GetBytes(originalPayload); 
      aes.GenerateIV(); 
      var iv = aes.IV; 

      using (var encrypter = aes.CreateEncryptor(aes.Key, iv)) 
      using (var cipherStream = new MemoryStream()) 
      { 
       using (var tCryptoStream = new CryptoStream(cipherStream, encrypter, CryptoStreamMode.Write)) 
       using (var tBinaryWriter = new BinaryWriter(tCryptoStream)) 
       { 
        //Prepend IV to data       
        cipherStream.Write(iv, 0, iv.Length); //Write iv to the plain stream (not tested though) 
        tBinaryWriter.Write(input); 
        tCryptoStream.FlushFinalBlock(); 
       } 

       encryptedPayload = Convert.ToBase64String(cipherStream.ToArray()); 
      } 

     } 

     return encryptedPayload; 
    } 

    static public string DecryptString(string data) 
    { 
     return DecryptString(Convert.FromBase64String(data), CipherKey); 
    } 

    static private string DecryptString(byte[] encryptedString, byte[] encryptionKey) 
    { 
     using (var provider = new AesCryptoServiceProvider()) 
     { 
      provider.Key = encryptionKey; 
      provider.Mode = CipherMode.CBC; 
      using (var ms = new MemoryStream(encryptedString)) 
      { 
       // Read the first 16 bytes which is the IV. 
       byte[] iv = new byte[16]; 
       ms.Read(iv, 0, 16); 
       provider.IV = iv; 
       using (var decryptor = provider.CreateDecryptor()) 
       { 
        using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read)) 
        { 
         using (var sr = new StreamReader(cs)) 
         { 
          return sr.ReadToEnd(); 
         } 
        } 
       } 
      } 
     } 
    } 

更新 我發現使用PCLCrypto一些代碼,但不能讓它工作的權利。解密後的字符串變成了正方形。

這是我試圖用來解密服務器的字符串。

public static string DecryptAes(byte[] data, byte[] key) 
    {    
     ISymmetricKeyAlgorithmProvider aes = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmName.Aes, 
      SymmetricAlgorithmMode.Cbc, SymmetricAlgorithmPadding.None); 
     ICryptographicKey symetricKey = aes.CreateSymmetricKey(key); 

     string returnValue = ""; 

     using (var ms = new MemoryStream(data)) 
     { 
      // Read the first 16 bytes which is the IV. 
      byte[] iv = new byte[16]; 
      ms.Read(iv, 0, 16);     
      using (var decryptor = WinRTCrypto.CryptographicEngine.CreateDecryptor(symetricKey, iv)) 
      { 
       using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read)) 
       { 
        using (var sr = new StreamReader(cs)) 
        { 
         returnValue = sr.ReadToEnd(); 
        } 
       } 
      } 
     } 
     return returnValue; 
    } 
+0

而你的服務器是寫在? – SushiHangover

+0

問題是什麼?加密代碼非常標準,所以不應該有任何困難。你需要提供一個嘗試,這不是一個代碼編寫服務。 – zaph

+0

從我發現的內容來看,Xamarin中沒有AesCryptoServiceProvider類。 – jbassking10

回答

0

我能夠得到它的工作。如果有人遇到同樣的問題,這裏是代碼。

static public string Encrypt(string originalPayload, byte[] privateKey) 
    { 
     string encryptedPayload = ""; 

     ISymmetricKeyAlgorithmProvider aes = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesCbcPkcs7); 
     ICryptographicKey symetricKey = aes.CreateSymmetricKey(privateKey); 
     var iv = WinRTCrypto.CryptographicBuffer.GenerateRandom(aes.BlockLength); 

     var input = Encoding.UTF8.GetBytes(originalPayload); 

     using (var encrypter = WinRTCrypto.CryptographicEngine.CreateEncryptor(symetricKey, iv)) 
     { 
      using (var cipherStream = new MemoryStream()) 
      { 
       using (var tCryptoStream = new CryptoStream(cipherStream, encrypter, CryptoStreamMode.Write)) 
       using (var tBinaryWriter = new BinaryWriter(tCryptoStream)) 
       { 
        //Prepend IV to data       
        cipherStream.Write(iv, 0, iv.Length); //Write iv to the plain stream (not tested though) 
        tBinaryWriter.Write(input); 
        tCryptoStream.FlushFinalBlock(); 
       } 

       encryptedPayload = Convert.ToBase64String(cipherStream.ToArray()); 
      } 
     } 

     return encryptedPayload; 
    } 

    public static string DecryptAes(byte[] data, byte[] key) 
    { 
     ISymmetricKeyAlgorithmProvider aes = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesCbcPkcs7); 
     ICryptographicKey symetricKey = aes.CreateSymmetricKey(key); 

     string returnValue = ""; 

     using (var ms = new MemoryStream(data)) 
     { 
      // Read the first 16 bytes which is the IV. 
      byte[] iv = new byte[16]; 
      ms.Read(iv, 0, 16); 
      using (var decryptor = WinRTCrypto.CryptographicEngine.CreateDecryptor(symetricKey, iv)) 
      { 
       using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read)) 
       { 
        using (var sr = new StreamReader(cs)) 
        { 
         returnValue = sr.ReadToEnd(); 
        } 
       } 
      } 
     } 
     return returnValue; 
    } 
相關問題