2015-08-14 4 views
2

Я использую алгоритм шифрования/дешифрования AES в своем приложении.Шифрование/дешифрование AES от C# до java

На стороне сервера я использую C# для шифрования/дешифрования данных.

И на стороне клиента (андроид) Я использую java для дешифрования данных.

C# шифрования/дешифрования код метода

static readonly string PasswordHash = "52"; 

    static readonly string SaltKey = "dfkjsadfinewdfadsfkmeoinmsdflksdflk"; 

    static readonly string VIKey = "@EUBRHDFBFG8867"; 

public static string Encrypt(string plainText) 
    { 
     byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText); 

     byte[] keyBytes = new Rfc2898DeriveBytes(PasswordHash,Encoding.ASCII.GetBytes(SaltKey)).GetBytes(256/8); 

     var symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC, Padding =PaddingMode.Zeros }; 

     var encryptor = symmetricKey.CreateEncryptor(keyBytes,Encoding.ASCII.GetBytes(VIKey)); 
     byte[] cipherTextBytes; 

     using (var memoryStream = new MemoryStream()) 
     { 
      using (var cryptoStream = new CryptoStream(memoryStream, encryptor,CryptoStreamMode.Write)) 
      { 
       cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length); 
       cryptoStream.FlushFinalBlock(); 
       cipherTextBytes = memoryStream.ToArray(); 
       cryptoStream.Close(); 
      } 
      memoryStream.Close(); 
     }   
     return Convert.ToBase64String(cipherTextBytes); 
    } 

    public static string Decrypt(string encryptedText) 
    { 
     byte[] cipherTextBytes = Convert.FromBase64String(encryptedText); 

     byte[] keyBytes = new Rfc2898DeriveBytes(PasswordHash,Encoding.ASCII.GetBytes(SaltKey)).GetBytes(256/8); 

     var symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC, Padding =PaddingMode.None } 

     var decryptor = symmetricKey.CreateDecryptor(keyBytes,Encoding.ASCII.GetBytes(VIKey)); 

     var memoryStream = new MemoryStream(cipherTextBytes); 

     var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read); 

     byte[] plainTextBytes = new byte[cipherTextBytes.Length]; 

     int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length); 

     memoryStream.Close(); 
     cryptoStream.Close(); 

     return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount).TrimEnd("\0".ToCharArray()); 
    } 

Java дешифрование

public String decrypt(String dataToDecrypt) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidKeySpecException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, UnsupportedEncodingException 
{ 

    byte[] encryptedCombinedBytes = Base64.decodeBase64(dataToDecrypt.getBytes()); 

    String saltKey = "dfkjsadfinewdfadsfkmeoinmsdflksdflk"; 
    String password = "52"; 
    String IVKey = "@EUBRHDFBFG8867"; 

    PBKDF2Parameters p = new PBKDF2Parameters("HmacSHA256", "ASCII", saltKey.getBytes(), 8); 

    byte[] mEncryptedPassword = new PBKDF2Engine(p).deriveKey(password); 


    byte[] ivbytes = Arrays.copyOfRange(IVKey.getBytes(), 0, 16); 

    SecretKeySpec mSecretKeySpec = new SecretKeySpec(mEncryptedPassword, "AES"); 

    Cipher mCipher = Cipher.getInstance("AES/CBC/NoPadding"); 

    mCipher.init(Cipher.DECRYPT_MODE, mSecretKeySpec, new IvParameterSpec(ivbytes)); 

    byte[] encryptedTextBytes = Arrays.copyOfRange(encryptedCombinedBytes, 16, encryptedCombinedBytes.length); 

    byte[] decryptedTextBytes = mCipher.doFinal(encryptedTextBytes); 

    return new String(decryptedTextBytes, "UTF-8"); 
} 

C# метод дешифрования прекрасно работает и дает результирующую строку.

Я не могу понять проблему в коде дешифрования Java. Он работает и дает мне некоторую ценность для мусора.

EDIT

  1. Я ничего не могу на side.I сервере редактировать просто копировать расшифровку в java дешифрования.
  2. Я не знаю, как использовать passwordHash, saltKey и IVkey
+0

Вы убедились, что все ключевые значения правильны и т. Д.? –

+1

Возможный дубликат [AES Encrypt in C# (Справка) и Расшифровка в Java (Готово)] (http://stackoverflow.com/questions/3632392/aes-encrypt-in-c-sharp-help-and-decrypt-in -java-done) –

+0

Использование CBC через сетевые подключения совершенно небезопасно. Desist и использовать TLS, возможно, используя самоподписанные сертификаты клиента и сервера + набор шифров GCM. –

ответ

1

Прежде всего, вы перешли пароль и соль вокруг.

Во-вторых, PBKDF2 по умолчанию использует HMAC/SHA-1. Насколько я знаю, что это также по умолчанию для Rfc2898DeriveBytes:

Реализует на основе пароля функциональность ключ вывод, PBKDF2, с помощью генератора псевдослучайных чисел, основанный на HMACSHA1.

Вы также никогда не должны звонить getBytes без указания набора символов в Java, но это, вероятно, не является проблемой для текущей среды выполнения.


Это только комментарии к коду; не используют CBC через сетевые соединения без защиты целостности/аутентификации.