2015-01-21 2 views
0

Мне нужно подражать и JavaScript-код на Android, чтобы выполнить AES encrytion и decrytion, но мой код Android не работает как код JavaScrip.AES encrypt with android из кода JavaScript

я должен сделать то же самое, как этот код в JavaScript:

<html> 
<head> 
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/aes.js"></script> 
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/components/pad-zeropadding-min.js"></script>  
<!-- jquery --> 
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> 
</head> 
<body> 
<div id="0"></div> 
<div id="1"></div> 
<div id="2"></div> 
<div id="3"></div> 
<div id="4"></div> 
<script> 
var key = CryptoJS.enc.Utf8.parse('a5240ba5b7cbde89e8075db30138ce64'); 
var iv = CryptoJS.enc.Utf8.parse('1ec9b4a4767e582b8a1e3dcad1782f80'); 
var message = "message"; 
$('#0').text("Message: "+message); 
var encrypted = CryptoJS.AES.encrypt(message, key, { iv: iv, padding: CryptoJS.pad.ZeroPadding, mode: CryptoJS.mode.CBC}); 
$('#1').text("Encrypted BASE64: "+encrypted); 
$('#2').text("Encrypted HEX: "+encrypted.ciphertext); 

var decrypted = CryptoJS.AES.decrypt(encrypted,key, { iv: iv, padding: CryptoJS.pad.ZeroPadding, mode: CryptoJS.mode.CBC}); 
$('#3').text("Decrypted HEX: "+decrypted); 
$('#4').text("Decrypted TEXT: "+decrypted.toString(CryptoJS.enc.Utf8)); 
</script> 
</body> 
</html> 

я должен сделать это с BouncyCastle Lib, поскольку IV имеет длину 32 байта, как вы можете видеть, я это делаю, но мой код Безразлично 't возвращаем то же самое, что и этот код JavaScript. Кто-нибудь знает, что я делаю неправильно, в коде Android?

Это андроид код:

private static final String ZERO_PADDING_KEY = "a5240ba5b7cbde89e8075db30138ce64"; 
private static final String IV = "1ec9b4a4767e582b8a1e3dcad1782f80"; 
public String encryptURL(String url) { 
    try { 
     Hex hex = new Hex(); 

     byte[] key = ZERO_PADDING_KEY.getBytes("UTF-8"); 
     byte[] iv = IV.getBytes("UTF-8"); 

     PaddedBufferedBlockCipher c = new PaddedBufferedBlockCipher(new CBCBlockCipher(new RijndaelEngine(256)), new ZeroBytePadding()); 
     c.init(true, new ParametersWithIV(new KeyParameter(key), iv)); 

     byte[] res = cipherData(c, url.getBytes("UTF-8")); 
     String resul = bytesToHex(res); 

     return resul; 
    } catch (Exception e) { 
     Log.e("ENCRYPT ERROR", e.getMessage()); 
     e.printStackTrace(); 
    } 
    return ""; 
} 

public String decryptUrl(String encrypted) { 
    try { 
     Hex hex = new Hex(); 
     byte[] key = ZERO_PADDING_KEY.getBytes("UTF-8"); 
     byte[] iv = IV.getBytes("UTF-8"); 


     PaddedBufferedBlockCipher c = new PaddedBufferedBlockCipher(new CBCBlockCipher(new RijndaelEngine(256)), new ZeroBytePadding()); 
     c.init(false, new ParametersWithIV(new KeyParameter(key), iv)); 

     byte[] decryptedText = cipherData(c, (byte[]) hex.decode(encrypted)); 
     String decrypted = new String(decryptedText, "UTF-8"); 
     Log.d("DECRYPTED", decrypted); 

     return decrypted; 
    } catch (Exception e) { 
     try { 
      throw new CryptoException("Unable to decrypt", e); 
     } catch (CryptoException e1) { 
      // TODO Auto-generated catch block 
      e1.printStackTrace(); 
     } 
    } 
    return ""; 
} 

private static byte[] cipherData(PaddedBufferedBlockCipher cipher, byte[] data) throws Exception { 

    int minSize = cipher.getOutputSize(data.length); 
    byte[] outBuf = new byte[minSize]; 
    int length1 = cipher.processBytes(data, 0, data.length, outBuf, 0); 
    int length2 = cipher.doFinal(outBuf, length1); 
    int actualLength = length1 + length2; 
    byte[] result = new byte[actualLength]; 
    System.arraycopy(outBuf, 0, result, 0, result.length); 
    return result; 
} 

public static String bytesToHex(byte[] bytes) { 
    char[] hexChars = new char[bytes.length * 2]; 
    for (int j = 0; j < bytes.length; j++) { 
     int v = bytes[j] & 0xFF; 
     hexChars[j * 2] = hexArray[v >>> 4]; 
     hexChars[j * 2 + 1] = hexArray[v & 0x0F]; 
    } 
    return new String(hexChars); 
} 

ответ

1

Вы new RijndaelEngine(256) в вашем Android код. Это Rijndael с размером блока 256. CryptoJS поддерживает только AES, который является Rijndael с размером блока 128.

Поскольку CryptoJS поддерживает только AES с размером блока 128, размер IV также должен быть 128. Вы должны проанализируйте IV как Hex. CryptoJS, похоже, не возражает против того, что передается больше IV. В CryptoJS:

var iv = CryptoJS.enc.Hex.parse('1ec9b4a4767e582b8a1e3dcad1782f80'); 

А в Android вы можете использовать класс Hex, что у вас уже есть в вашем коде.

Если вы не хотите, чтобы изменить код JavaScript, вы можете использовать только первый 128-бит IV в Android (я подозреваю, что это то, что делает CryptoJS, но не мог проверить его):

byte[] iv = Arrays.copyOf(IV.getBytes("UTF-8"), 16); 
+0

Но если я поставил RijndaelEngine (128), у меня есть это исключение: java.lang.IllegalArgumentException: вектор инициализации должен быть такой же длины, как размер блока –

+0

Да, у вас такая же проблема в JavaScript, но это не похоже на вызвать ошибку. –

+0

Кстати, IV предполагается случайным для каждого зашифрованного текста. Просто так вы знаете. Как правило, это префикс шифрованного текста и разрезается перед расшифровкой. –