ricmoo / aes-js

A pure JavaScript implementation of the AES block cipher and all common modes of operation for node.js or web browsers.
MIT License
1.45k stars 273 forks source link

Encrypted text using AES/ECB/PCKS7Padding diffs from java #61

Open gushengyuan opened 6 years ago

gushengyuan commented 6 years ago

When use AES/ECB/PCKS7Padding to encrypt text, the result is defferent form aes-js and java.

Here is the js code using aes-js: `// Convert text to bytes var text = 'this is a string will be AES_Encrypt'; var textBytes = aesjs.utils.utf8.toBytes(text); var padded = aesjs.padding.pkcs7.pad(textBytes);

// An example 128-bit key var key = "UITN25LMUQC436IM"; var keyBytes = aesjs.utils.utf8.toBytes(key); var aesEcb = new aesjs.ModeOfOperation.ecb(keyBytes); var encryptedBytes = aesEcb.encrypt(padded);

// To print or store the binary data, you may convert it to hex var encryptedHex = aesjs.utils.hex.fromBytes(encryptedBytes); console.log(encryptedHex);

// When ready to decrypt the hex string, convert it back to bytes var encryptedBytes = aesjs.utils.hex.toBytes(encryptedHex); var encryptedText = aesjs.utils.utf8.fromBytes(encryptedBytes);

var base = new Base64();
var encryptedBase64 = base.encode(encryptedText); //should be: fhTD0NNIzv4jUEhJuC1htFFXJ/4S/rL6tDCJPiNvJ8mVLHWOD0HWweuxHynxoZf9

// Since electronic codebook does not store state, we can // reuse the same instance. //var aesEcb = new aesjs.ModeOfOperation.ecb(key); var decryptedBytes = aesEcb.decrypt(encryptedBytes);

// Convert our bytes back into text var decryptedText = aesjs.utils.utf8.fromBytes(decryptedBytes); console.log(decryptedText); // "this is a string will be AES_Encrypt"

function Base64() {

// private property
_keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

// public method for encoding
this.encode = function (input) {
    var output = "";
    var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
    var i = 0;
    input = _utf8_encode(input);
    while (i < input.length) {
        chr1 = input.charCodeAt(i++);
        chr2 = input.charCodeAt(i++);
        chr3 = input.charCodeAt(i++);
        enc1 = chr1 >> 2;
        enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
        enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
        enc4 = chr3 & 63;
        if (isNaN(chr2)) {
            enc3 = enc4 = 64;
        } else if (isNaN(chr3)) {
            enc4 = 64;
        }
        output = output +
        _keyStr.charAt(enc1) + _keyStr.charAt(enc2) +
        _keyStr.charAt(enc3) + _keyStr.charAt(enc4);
    }
    return output;
}

// public method for decoding
this.decode = function (input) {
    var output = "";
    var chr1, chr2, chr3;
    var enc1, enc2, enc3, enc4;
    var i = 0;
    input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
    while (i < input.length) {
        enc1 = _keyStr.indexOf(input.charAt(i++));
        enc2 = _keyStr.indexOf(input.charAt(i++));
        enc3 = _keyStr.indexOf(input.charAt(i++));
        enc4 = _keyStr.indexOf(input.charAt(i++));
        chr1 = (enc1 << 2) | (enc2 >> 4);
        chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
        chr3 = ((enc3 & 3) << 6) | enc4;
        output = output + String.fromCharCode(chr1);
        if (enc3 != 64) {
            output = output + String.fromCharCode(chr2);
        }
        if (enc4 != 64) {
            output = output + String.fromCharCode(chr3);
        }
    }
    output = _utf8_decode(output);
    return output;
}

// private method for UTF-8 encoding
_utf8_encode = function (string) {
    string = string.replace(/\r\n/g,"\n");
    var utftext = "";
    for (var n = 0; n < string.length; n++) {
        var c = string.charCodeAt(n);
        if (c < 128) {
            utftext += String.fromCharCode(c);
        } else if((c > 127) && (c < 2048)) {
            utftext += String.fromCharCode((c >> 6) | 192);
            utftext += String.fromCharCode((c & 63) | 128);
        } else {
            utftext += String.fromCharCode((c >> 12) | 224);
            utftext += String.fromCharCode(((c >> 6) & 63) | 128);
            utftext += String.fromCharCode((c & 63) | 128);
        }

    }
    return utftext;
}

// private method for UTF-8 decoding
_utf8_decode = function (utftext) {
    var string = "";
    var i = 0;
    var c = c1 = c2 = 0;
    while ( i < utftext.length ) {
        c = utftext.charCodeAt(i);
        if (c < 128) {
            string += String.fromCharCode(c);
            i++;
        } else if((c > 191) && (c < 224)) {
            c2 = utftext.charCodeAt(i+1);
            string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
            i += 2;
        } else {
            c2 = utftext.charCodeAt(i+1);
            c3 = utftext.charCodeAt(i+2);
            string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
            i += 3;
        }
    }
    return string;
}

}`

Here is the java code: `import java.security.Key; import java.security.Security;

import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.jce.provider.BouncyCastleProvider;

import org.apache.commons.codec.binary.Base64;

public class TestAes {

private static final String AESTYPE ="AES/ECB/PKCS7Padding";

public static String AES_Encrypt(String keyStr, String plainText) { 
    byte[] encrypt = null; 
    try{ 
        Key key = generateKey(keyStr);
        Cipher cipher = Cipher.getInstance(AESTYPE, "BC"); 
        cipher.init(Cipher.ENCRYPT_MODE, key); 
        encrypt = cipher.doFinal(plainText.getBytes());
    }catch(Exception e){ 
        e.printStackTrace(); 
    }

    return new String(Base64.encodeBase64(encrypt)); 
}

public static String AES_Decrypt(String keyStr, String encryptData) {
    byte[] decrypt = null; 
    try{ 
        Key key = generateKey(keyStr); 
        Cipher cipher = Cipher.getInstance(AESTYPE, "BC"); 
        cipher.init(Cipher.DECRYPT_MODE, key); 
        decrypt = cipher.doFinal(Base64.decodeBase64(encryptData)); 
    }catch(Exception e){ 
        e.printStackTrace(); 
    } 
    return new String(decrypt).trim(); 
} 

private static Key generateKey(String key)throws Exception{ 
    try{            
        SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "AES"); 
        return keySpec; 
    }catch(Exception e){ 
        e.printStackTrace(); 
        throw e; 
    } 

} 

public static void main(String[] args) { 
    Security.addProvider(new BouncyCastleProvider());
    String keyStr = "UITN25LMUQC436IM";  

    String plainText = "this is a string will be AES_Encrypt";

    String encText = AES_Encrypt(keyStr, plainText);
    String decString = AES_Decrypt(keyStr, encText); 

    System.out.println(encText); 
    System.out.println(decString); 

} 

}`

RokerHRO commented 6 years ago

Where do you do the PKCS#7 padding in your Java example?

Ruffio commented 6 years ago

@gushengyuan can this issue be closed? You havn't responded on @RokerHRO's question for more than a month...