最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

aes - Different output encryption both CryptoJS and Java Code - Stack Overflow

programmeradmin3浏览0评论

I need to encrypt certainly string from client-side (JavaScript) and decrypt from server-side (Java), so I found CryptoJS and I write the code with the same params/configuration of mi Java Code but the output is always different, do you have any idea or what happen?

I'm use CBC with NoPadding

CryptoJS

/

<script src=".1.2/build/rollups/aes.js">
</script>
<script src=".1.2/build/ponents/pad-nopadding-min.js"></script>
<script>

    function padString(source) {
        var paddingChar = ' ';
        var size = 16;
        var x = source.length % size;
        var padLength = size - x;

        for (var i = 0; i < padLength; i++) source += paddingChar;

        return source;
    }

    var key = CryptoJS.enc.Hex.parse('0123456789abcdef');
    var iv  = CryptoJS.enc.Hex.parse('fedcba9876543210');
    var message = "soldier";
    var padMsg = padString(message);

    var encrypted = CryptoJS.AES.encrypt(padMsg, key, { iv: iv, padding: CryptoJS.pad.NoPadding, mode: CryptoJS.mode.CBC});

    console.log("Encrypted: "+encrypted);
    console.log("Encrypted text: "+encrypted.ciphertext);

</script>

Java Code

import java.security.Key;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import sun.misc.*;

public class AesCipher {

    private static final String algorithm = "AES/CBC/NoPadding";

    private static final byte[] keyValue = new byte[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
    private static final byte[] ivValue = new byte[] { 'f', 'e', 'd', 'c', 'b', 'a', '9', '8', '7', '6', '5', '4', '3', '2', '1', '0' };

    private static final IvParameterSpec ivspec = new IvParameterSpec(ivValue);
    private static final SecretKeySpec keyspec = new SecretKeySpec(keyValue, "AES");

    final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();

    public static String encrypt(String Data) throws Exception {
        Cipher c = Cipher.getInstance(algorithm);
        c.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
        byte[] encVal = c.doFinal(Data.getBytes());
        String encryptedValue = new BASE64Encoder().encode(encVal);
        return encryptedValue;
    }

    public static String decrypt(String encryptedData) throws Exception {
        Cipher c = Cipher.getInstance(algorithm);
        c.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
        byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedData);
        byte[] decValue = c.doFinal(decordedValue);
        String decryptedValue = new String(decValue);
        return decryptedValue;
    }

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

    private static String padString(String source) {
        char paddingChar = ' ';
        int size = 16;
        int x = source.length() % size;
        int padLength = size - x;

        for (int i = 0; i < padLength; i++)
        {
            source += paddingChar;
        }
        return source;
      }

    public static void main(String[] args) throws Exception {

        String password = "soldier";
        String passwordEnc = AesCipher.encrypt(padString(password));
        String passwordDec = AesCipher.decrypt(passwordEnc);

        System.out.println("Plain Text : " + password);
        System.out.println("Encrypted Text : " + passwordEnc);
        System.out.println("Decrypted Text : " + passwordDec);
    }

}

Original string:

soldier

Output from CryptoJS:

Encrypted: VNzZNKJTqfRbM7zO/M4cDQ==
Encrypted Hex: 54dcd934a253a9f45b33bccefcce1c0d

Output from Java Code:

Encrypted: j6dSmg2lfjY2RpN91GNgNw==
Encrypted Hex: 6a3664536d67326c666a593252704e3931474e674e773d3d

The base64 string encrypted has same length but not the hex. If I put the output result of CryptoJS in Java Code, the decryption is incorrect.

Regards,

I need to encrypt certainly string from client-side (JavaScript) and decrypt from server-side (Java), so I found CryptoJS and I write the code with the same params/configuration of mi Java Code but the output is always different, do you have any idea or what happen?

I'm use CBC with NoPadding

CryptoJS

http://jsfiddle/Soldier/gCHAG/

<script src="http://crypto-js.googlecode./svn/tags/3.1.2/build/rollups/aes.js">
</script>
<script src="http://crypto-js.googlecode./svn/tags/3.1.2/build/ponents/pad-nopadding-min.js"></script>
<script>

    function padString(source) {
        var paddingChar = ' ';
        var size = 16;
        var x = source.length % size;
        var padLength = size - x;

        for (var i = 0; i < padLength; i++) source += paddingChar;

        return source;
    }

    var key = CryptoJS.enc.Hex.parse('0123456789abcdef');
    var iv  = CryptoJS.enc.Hex.parse('fedcba9876543210');
    var message = "soldier";
    var padMsg = padString(message);

    var encrypted = CryptoJS.AES.encrypt(padMsg, key, { iv: iv, padding: CryptoJS.pad.NoPadding, mode: CryptoJS.mode.CBC});

    console.log("Encrypted: "+encrypted);
    console.log("Encrypted text: "+encrypted.ciphertext);

</script>

Java Code

import java.security.Key;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import sun.misc.*;

public class AesCipher {

    private static final String algorithm = "AES/CBC/NoPadding";

    private static final byte[] keyValue = new byte[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
    private static final byte[] ivValue = new byte[] { 'f', 'e', 'd', 'c', 'b', 'a', '9', '8', '7', '6', '5', '4', '3', '2', '1', '0' };

    private static final IvParameterSpec ivspec = new IvParameterSpec(ivValue);
    private static final SecretKeySpec keyspec = new SecretKeySpec(keyValue, "AES");

    final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();

    public static String encrypt(String Data) throws Exception {
        Cipher c = Cipher.getInstance(algorithm);
        c.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
        byte[] encVal = c.doFinal(Data.getBytes());
        String encryptedValue = new BASE64Encoder().encode(encVal);
        return encryptedValue;
    }

    public static String decrypt(String encryptedData) throws Exception {
        Cipher c = Cipher.getInstance(algorithm);
        c.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
        byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedData);
        byte[] decValue = c.doFinal(decordedValue);
        String decryptedValue = new String(decValue);
        return decryptedValue;
    }

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

    private static String padString(String source) {
        char paddingChar = ' ';
        int size = 16;
        int x = source.length() % size;
        int padLength = size - x;

        for (int i = 0; i < padLength; i++)
        {
            source += paddingChar;
        }
        return source;
      }

    public static void main(String[] args) throws Exception {

        String password = "soldier";
        String passwordEnc = AesCipher.encrypt(padString(password));
        String passwordDec = AesCipher.decrypt(passwordEnc);

        System.out.println("Plain Text : " + password);
        System.out.println("Encrypted Text : " + passwordEnc);
        System.out.println("Decrypted Text : " + passwordDec);
    }

}

Original string:

soldier

Output from CryptoJS:

Encrypted: VNzZNKJTqfRbM7zO/M4cDQ==
Encrypted Hex: 54dcd934a253a9f45b33bccefcce1c0d

Output from Java Code:

Encrypted: j6dSmg2lfjY2RpN91GNgNw==
Encrypted Hex: 6a3664536d67326c666a593252704e3931474e674e773d3d

The base64 string encrypted has same length but not the hex. If I put the output result of CryptoJS in Java Code, the decryption is incorrect.

Regards,

Share Improve this question asked Oct 17, 2013 at 20:51 SoldierCorpSoldierCorp 7,70016 gold badges63 silver badges103 bronze badges 0
Add a ment  | 

3 Answers 3

Reset to default 8

The problem here is that your key input in inconsistent.

  • CryptoJS.enc.Hex.parse('0123456789abcdef') reads the input as a series of bytes expressed as two-digit hex values: 01, 23, 45, etc.

  • Your Java array specifies byte values using the character-encoding values of the characters. So, the sequence of bytes (in hex) is: 30 (decimal 48, ASCII code for '0'), then 31 (decimal 49, ASCII code for '1'), etc.

You can make the JavaScript conform to the the Java implementation by using CryptoJS.enc.Latin1.parse which will read in the individual character values and use them as byte values: http://jsfiddle/gCHAG/1/ (this produces the same j6dSm... output)

However, you probably want each digit to be its own byte. To do that, you need to change both implementations.

Java:

// use hex literals, not characters
byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F };
// array values: 0x00, 0x01, 0x02, etc

JavaScript:

// remember each bytes is two digits wide
CryptoJS.enc.Hex.parse('000102030405060708090a0b0c0d0e0f')
// array values: 0x00, 0x01, 0x02, etc

The character '0' is not the same as hex value 0. The CryptoJS key is most likely different than the Java key because you're instantiating them as different object types. Print out the keys/IV in both languages after creating them and pare.

EDIT: That said, this will probably be moved to StackOverflow, as questions about specific crypto libraries are not on-topic here.

Very usefull example SoldierCorp, thank you!

Few things to improve your example:

  • Method padString does not support UTF8 and instead of fixing this method lets delete it and use a standard padding

in javascript replace on

padding: CryptoJS.pad.Pkcs7

in java replace on

algorithm = "AES/CBC/PKCS5Padding"
  • Generate key from any string phrase (for IV can be the same)

in javascript replace on

var key = CryptoJS.MD5("Secret Passphrase");

in java replace on

byte[] keyValue = org.apache.mons.codec.digest.DigestUtils.md5("Secret Passphrase");
发布评论

评论列表(0)

  1. 暂无评论