2016-08-10 2 views
0

저는 AES 암호화 및 해독을위한 자바 알고리즘을 가지고 있으며 자바 스크립트에서 해독을 실현해야합니다.decryptAES from Java to node.js

public String encryptWithAES(String value, String key, String encoding) throws NoSuchAlgorithmException, NoSuchPaddingException, DecoderException, UnsupportedEncodingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { 
    byte[] keyBytes = Hex.decodeHex(key.toLowerCase().toCharArray()); 
    byte[] dataToSend = value.getBytes(encoding); 
    Cipher c = Cipher.getInstance("AES"); 
    SecretKeySpec k = new SecretKeySpec(keyBytes, "AES"); 
    c.init(1, k); 
    byte[] encryptedData = c.doFinal(dataToSend); 
    return new String(Hex.encodeHex(encryptedData)); 
} 

public String decryptAES(String encrypted, String key, String encoding) throws NoSuchAlgorithmException, NoSuchPaddingException, DecoderException, UnsupportedEncodingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { 
    byte[] keyBytes = Hex.decodeHex(key.toCharArray()); 
    byte[] encryptedData = Hex.decodeHex(encrypted.toCharArray()); 
    Cipher c = Cipher.getInstance("AES"); 
    SecretKeySpec k = new SecretKeySpec(keyBytes, "AES"); 
    c.init(2, k); 
    byte[] dencryptedData = c.doFinal(encryptedData); 
    return new String(dencryptedData, encoding); 
} 

인터넷에서 많은 예제를 발견했지만 아무도 적절한 결과를 얻지 못했습니다.

var algos = ['aes-128-cbc', 'aes-128-cfb', 'aes-128-cfb1', 'aes-128-cfb8', 'aes-128-ctr', 'aes-128-ecb', 'aes-128-gcm', 'aes-128-ofb', 'aes-128-xts', 'aes-256-cbc', 'aes-256-cfb', 'aes-256-cfb1', 'aes-256-cfb8', 'aes-256-ctr', 'aes-256-ecb', 'aes-256-gcm', 'aes-256-ofb', 'aes-256-xts', 'aes128', 'aes256']; 
//var masterData - string like 'c07abe96dde490b3aba7d2f21a43ba94960619ff110ffb53433f0ff39f4cf138e48511b1fb4030' 
//const ENCRYPTION_KEY - string like '94960619ff110ffb53433f0ff39f4cf1' with 32 symbols 

function decrypt(text, algorithm) { 
    var decipher = crypto.createDecipher(algorithm, ENCRYPTION_KEY); 

    var dec = decipher.update(text, 'hex', 'utf8'); 

    dec += decipher.final('utf8'); 
    return dec; 
} 

algos.map(algo => { 
    try { 
     const dec = decrypt(masterData, algo); 

     console.log(algo, dec); 
    } catch (error) { 
     console.log(algo, 'error', error); 
    } 
}); 

인코딩 된 문자열은 JSON입니다 :

는 지금은 그 코드를 해독하려고합니다.

+0

Maven 알고리즘에 대해 이야기하고 있습니다. 그게 무슨 뜻입니까? Maven은 도구이며 알고리즘은 Java 기반입니까? – khmarbaise

+0

예. 알고리즘은 maven 라이브러리에서 가져온 것입니다. http://grepcode.com/file/repo1.maven.org/maven2/com.google.code.maven-play-plugin.org.playframework/play/1.2.5/play/ libs/Crypto.java – MIchael

답변

0

이것은 실제로 안전하지 않은 코드이므로 절대로 사용해서는 안됩니다.

Cipher.getInstance("AES");은 기본 보안 공급자에 따라 다른 암호가 지정 될 수 있습니다. 대부분 "AES/ECB/PKCS5Padding"이 될 수 있지만 그럴 필요는 없습니다. 변경되면 다른 JVM 간의 호환성이 손실됩니다.
항상 정규화 된 Cipher 문자열을 사용하십시오.

그래서 가장 먼저 시도해야 할 것은 암호를 ECB 모드로 제한하는 것입니다. Node.js의 암호화 모듈은 PKCS # 5/PKCS # 7 패딩을 자동으로 적용하므로 특별한 점이 없습니다.

다음은 열쇠입니다. 예제 키는 32 자입니다. Java 코드를 살펴보면 16 진 인코딩으로되어 있기 때문에 실제로는 키가 16 바이트 (128 비트) 밖에되지 않는다는 것을 의미합니다. 키를 사용하기 전에 16 진수에서 키를 해독해야합니다.

또 다른 문제는 crypto.createDecipher은 암호가 매개 변수로 필요하지만 키가있는 것 같습니다. 이 경우 crypto.createDecipheriv을 사용해야합니다. 암호와 키를 혼동하지 마십시오. 그것들은 매우 다른 속성을 가지고 있지만 좋은 점은 패스워드로 키를 파생시킬 수 있다는 것입니다. 자세한 내용은 다음을 참조하십시오. How to securely hash passwords?

앞서 말했듯이 Java는 패딩을 사용합니다. 많은 조작 모드 은 임의로 긴 일반 텍스트를 암호화하기 위해 패딩을 사용하여이 필요합니다. 그들 중 하나는 ECB 모드입니다. 패딩은 1에서 16 바이트 사이에 추가합니다 (16 바이트는 AES의 블록 크기 임). 즉, 암호문은 32 문자 (16 진수로 인코딩 된)의 배수 여야합니다. 그렇지 않으면 유효한 암호 텍스트가 아닙니다.

테스트되지 않은 코드는 예를 들어 암호문이 올바르지 않기 때문에 :

var crypto = require('crypto'); 

var masterData = '...'; // multiple of 32 characters! 
var ENCRYPTION_KEY = '94960619ff110ffb53433f0ff39f4cf1'; 

function decrypt(text, key) { 
    var decipher = crypto.createDecipheriv('aes-128-ecb', new Buffer(key, 'hex'), ''); 

    var dec = decipher.update(text, 'hex', 'utf8'); 

    dec += decipher.final('utf8'); 
    return dec; 
} 

console.log(decrypt(masterData, ENCRYPTION_KEY)); 

이 코드는 정말 안전하지 : ECB 모드를 사용, 무작위하지, 인증 없음! 이 암호 코드를 전혀 사용하지 않아야합니다.

+0

예. 그것은 내 문제를 해결합니다! 정말 고마워! – MIchael