예 1:
요즘 문제가 있어서 고민이에요. Nodejs의 AES 암호화는 Java 및 C#의 암호화와 일치하지 않습니다. 물론 이 내용은 해독할 수 없습니다. 오랫동안 고생했습니다. 결국 더 이상 할 수 없어서 소스 코드를 살펴보았습니다. 그렇지 않으면 계속해서 고생해야 했습니다. 인터넷에서는 일반적인 nodejs AES 구현이 다른 언어와 다르다고 합니다. 알았어~~아마도.
nodejs용 암호화 모듈입니다.
var crypto = require(' 암호화') ;
var data = "156156165152165156156";
console.log('원본 일반 텍스트: ' data);
var 알고리즘 = 'aes-128-ecb';
var key = '78541561566';
varclearEncoding = 'utf8';
//var cipherEncoding = 'hex';
//다음 줄의 주석 처리가 없으면 최종 일반 텍스트가 잘못된 것입니다.
var cipherEncoding = 'base64';
/*암호화*/
var cipher = crypto.createCipher(알고리즘, 키);
var cipherChunks = [];
cipherChunks.push(cipher.update(data,clearEncoding, cipherEncoding));
cipherChunks.push(cipher.final(cipherEncoding));
console.log( cipherEncoding ' ciphertext: ' cipherChunks.join(''));
/*decryption*/
var decipher = crypto.createDecipher(algorithm, key);
var plainChunks = [];
for (var i = 0;i < cipherChunks.length;i ) {
plainChunks.push(decipher.update(cipherChunks[i], cipherEncoding,clearEncoding));
}
plainChunks.push(decipher.final(clearEncoding));
console.log("UTF8 일반 텍스트 해독: " plainChunks.join(''));
그렇습니다. 틀렸어요~~암호화 및 복호화에 성공했습니다. 하지만 Java나 C#의 암호화와는 다릅니다. 하나님. 다들 여기서 고생하고 있는 것 같죠? 실제로 벡터를 추가하는 한 일관성이 유지됩니다. 온라인에서 찾을 수 있는 리소스가 너무 적습니다. 그래서 오랫동안 고생했어요.
올바른 코드는
var crypto = require('crypto');
var data = "156156165152165156156";
console.log('원본 일반 텍스트: ' data);
var 알고리즘 = 'aes-128-ecb';
var key = '78541561566';
varclearEncoding = 'utf8';
var iv = "";
//var cipherEncoding = 'hex';
//다음 줄의 주석 처리가 없으면 최종 일반 텍스트가 잘못된 것입니다.
var cipherEncoding = 'base64';
var cipher = crypto.createCipheriv(algorithm, key,iv);
var cipherChunks = [];
cipherChunks.push(cipher.update(data,clearEncoding, cipherEncoding));
cipherChunks.push(cipher.final(cipherEncoding));
console.log( cipherEncoding ' 암호문: ' cipherChunks.join(''));
var decipher = crypto.createDecipheriv(algorithm, key,iv);
var plainChunks = [];
for (var i = 0;i < cipherChunks.length;i ) {
plainChunks .push(decipher.update(cipherChunks[i], cipherEncoding,clearEncoding));
}
plainChunks.push(decipher.final(clearEncoding));
console.log("UTF8 일반 텍스트 해독: " plainChunks.join(''));
비교 결과 , 암호화가 일관됩니다. 알았어 매듭~~ 하루를 낭비하는 네가 미워.
예 2:
직장에서 AES와 Android 클라이언트 Java 복호화를 통해 nodejs 암호화를 접했습니다. nodejs도 Android 클라이언트에서 암호화한 콘텐츠를 복호화해야 한다는 데 동의했습니다. 데이터를 쿼리한 결과 두 가지 암호화 결과가 다르다는 것을 알았습니다. Java 측에서 MD5로 다시 암호화해야 함을 발견했습니다. 다음은 aes ecb 암호화의 내용입니다. cbc인 경우 비밀 키 MD5도 암호화해야 합니다.
nodejs:
/**
* aes 암호화
* @param data
* @param secretKey
*/
encryptUtils.aesEncrypt = function(data, secretKey) {
var cipher = crypto.createCipher('aes-128-ecb',secretKey);
return cipher.update(data,'utf8','hex') cipher.final('hex');
}
/**
* AES 복호화
* @param data
* @param secretKey
* @returns {*}
*/
encryptUtils.aesDecrypt = function(data, secretKey) {
var cipher = crypto.createDecipher('aes-128-ecb', 비밀키);
return cipher.update(data,'hex','utf8') cipher.final('utf8');
}
java:
패키지 com.iofamily.util;
java.security.MessageDigest 가져오기;
javax.crypto.Cipher 가져오기;
javax.crypto.spec.SecretKeySpec 가져오기;
/**
* Nodejs와 일치하는 AES 암호화
* @author lmiky
* @date 2014-2-25
*/
public class AESForNodejs {
public static final String DEFAULT_CODING = "utf-8";
/**
* 解密
* @author lmiky
* @date 2014-2-25
* @param 암호화됨
* @param seed
* @return
* @throws 예외
*/
개인 정적 문자열 해독(암호화된 문자열, 문자열 시드) 예외 발생 {
byte[] keyb = seed.getBytes(DEFAULT_CODING);
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] thedigest = md.digest(keyb);
SecretKeySpec skey = new SecretKeySpec(thedigest, "AES");
암호 dcipher = Cipher.getInstance("AES");
dcipher.init(Cipher.DECRYPT_MODE, skey);
byte[]clearbyte = dcipher.doFinal(toByte(암호화));
새 문자열 반환(clearbyte);
}
/**
* 加密
* @author lmiky
* @date 2014-2-25
* @param content
* @param key
* @return
* @throws 예외
*/
public static String encrypt(String content, String key) throws Exception {
byte[] input = content.getBytes(DEFAULT_CODING);
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] thedigest = md.digest(key.getBytes(DEFAULT_CODING));
SecretKeySpec skc = new SecretKeySpec(thedigest, "AES");
암호 암호 = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, skc);
byte[] cipherText = 새 바이트[cipher.getOutputSize(input.length)];
int ctLength = cipher.update(input, 0, input.length, cipherText, 0);
ctLength = cipher.doFinal(cipherText, ctLength);
returnparseByte2HexStr(cipherText);
}
/**
* 문자열을 바이트 배열로 변환
* @author lmiky
* @date 2014-2-25
* @param hexString
* @return
*/
private static byte[] toByte(String hexString) {
int len = hexString.length() / 2;
byte[] 결과 = 새 바이트[len];
for (int i = 0; i < len; i ) {
결과[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i 2), 16).byteValue() ;
}
결과 반환;
}
/**
* 바이트를 16진수 배열로
* @author lmiky
* @date 2014-2-25
* @param buf
* @return
*/
private static String parseByte2HexStr(byte buf[]) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < buf.length; i ) {
String hex = Integer.toHexString(buf[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' hex;
}
sb.append(hex);
}
return sb.toString();
}
public static void main(String[] args) throw Exception {
System.out.println(AESForNodejs.encrypt("fsadfsdafsdafsdafsadfsadfsadf", "1234fghjnmlkiuhA"));
System.out.println(AESForNodejs.decrypt("5b8e85b7a86ad15a275a7cb61fe4c0606005e8741f68797718a3e90d74b5092a", "1234fghjnmlkiuhA"));
}
}