>웹 프론트엔드 >JS 튜토리얼 >Node.js_javascript 기술의 AES 암호화와 다른 언어 간의 불일치에 대한 솔루션

Node.js_javascript 기술의 AES 암호화와 다른 언어 간의 불일치에 대한 솔루션

WBOY
WBOY원래의
2016-05-16 16:56:151651검색

예 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:
复system代码 代码如下:

패키지 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")); 
    } 
}
성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.