2010-01-22 21 views
5

El cifrado es en Java:Java codificar y .NET decodificación


String salt = "DC14DBE5F917C7D03C02CD5ADB88FA41"; 
String password = "25623F17-0027-3B82-BB4B-B7DD60DCDC9B"; 

char[] passwordChars = new char[password.length()]; 
password.getChars(0,password.length(), passwordChars, 0); 

SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); 
KeySpec spec = new PBEKeySpec(passwordChars, salt.getBytes(), 2, 256); 
SecretKey sKey = factory.generateSecret(spec); 
byte[] raw = _sKey.getEncoded(); 

String toEncrypt = "The text to be encrypted."; 

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC"); 
cipher.init(Cipher.ENCRYPT_MODE, skey); 

AlgorithmParameters params = cipher.getParameters(); 
byte[] initVector = params.getParameterSpec(IvParameterSpec.class).getIV(); 

byte[] encryptedBytes = cipher.doFinal(toEncrypt.getBytes()); 

Mientras que el descifrado es en C#:


string hashAlgorithm = "SHA1"; 
int passwordIterations = 2; 
int keySize = 256; 

byte[] saltValueBytes = Encoding.ASCII.GetBytes(salt); 
byte[] cipherTextBytes = Convert.FromBase64String(cipherText); 

PasswordDeriveBytes passwordDB = new PasswordDeriveBytes(password, saltValueBytes, hashAlgorithm passwordIterations); 

byte[] keyBytes = passwordDB.GetBytes(keySize/8); 

RijndaelManaged symmetricKey = new RijndaelManaged(); 
symmetricKey.Mode = CipherMode.CBC; 
ICryptoTransform decryptor = symmetricKey.CreateDecryptor(keyBytes, initVector); 

MemoryStream memoryStream = new MemoryStream(cipherTextBytes); 

CryptoStream 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(); 

string plainText = Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount); 

El descifrado fallado con la excepción "El relleno es válido y no se puede quitar. "

¿Alguna idea de cuál podría ser el problema?

Respuesta

5

Esto generalmente indica que el descifrado ha fallado. Sugiero que verifique la salida de las funciones de generación de claves, para ver si realmente está usando la misma clave. Observo, por ejemplo, que el código de Java implica que está utilizando un HMAC basado en SHA1, mientras que el código .NET implica que está utilizando un hash SHA1 no registrado para generar la clave.

Alternativamente, podría ser una falta de coincidencia en el relleno. No veo dónde está configurando explícitamente el PaddingMode en PKCS7 en el código .NET.

+0

Gracias por la respuesta. Básicamente, estoy codificando el lado java de él, y no tengo control sobre el lado .NET. Sin embargo, tengo el código fuente de ambos lados y al depurar el lado .NET, muestra el PKCS7. Supongo que mi pregunta sería, ¿qué debería hacer en el lado de java para que coincida con el descifrado de .NET existente? – Wijaya

+0

El 'PaddingMode' predeterminado en .NET es PKCS7, acabo de comprobar. Entonces sospecho que hay una diferencia en la generación de claves. 'PasswordDeriveBytes' utiliza el algoritmo PBKDF1, mientras que su código Java usa PBKDF2. No estoy lo suficientemente familiarizado con lo que está disponible en Java, pero ¿hay alguna manera de usar PBKDF1? –

+0

Hola David. Tienes razón, las llaves no coinciden. Resulta que BouncyCastle tiene una clase creada solo para esto. org.bouncycastle.crypto.generators.PKCS5S1ParametersGenerator yo encontramos este hilo muy útil: http://old.nabble.com/.NET-PasswordDeriveBytes-tt9114084.html#a9114084 Funciona ahora. Gracias por la visión. – Wijaya

Cuestiones relacionadas