CryptoJS.AES and Golang

I have already managed to split the random symmetric key via rsa. However, I cannot work with it. The problem appears to be the salt and initialization vector that cryptoJS uses.

First it is output line by line:

U2FsdGVkX19wbzVqqOr6U5dnuG34WyH+n1A4PX9Z+xBhY3bALGS7DOa/aphgnubc 

      

The search phrase to reinstall "U2FsdGVkX" or "cryptoJS.AES output" is unfortunately useless.

On the other hand, golang aes only requires a 32 bit key and a 32 bit length input each. This means that I have to somehow split this into appropriate blocks and figure out how to generate a 32-bit key from the secret key and the data above (which in turn includes the + init salt file).

Unfortunately, neither http://code.google.com/p/crypto-js nor any google search provide me with a solution.

By the way, my encryption right now:

var arr = new Array(32);
symetricKey = "";
var symHex = "";
rng.nextBytes(arr);
for(var i = 0; i < arr.length; i++){
    symetricKey += String.fromCharCode(arr[i]);
    //symHex= arr[i].toString(16), added a 0 if needed (so length always increases by 2)
}
//submit symetric via rsa. This is working, the server gets that key
var enc = CryptoJS.AES.encrypt(unencrypted, symetricKey)
//submit enc, stuck now - what to do with it on the server?

      


Edit: Following Base64's answer:
Thanks for the base64 input.
However, I am still having trouble getting it to work.
Especially since the encoded string starts with "SALTED", I believe there may be a problem.

Now I'm trying to code:
Encoded on the client:

var unencrypted = "{mail:test,password:test}"
var enc = CryptoJS.AES.encrypt(unencrypted, symKey)

      

On the server, the enc and symKey variables are the same as on the client:

baseReader := base64.NewDecoder(base64.StdEncoding, strings.NewReader(enc))
encData, err := ioutil.ReadAll(baseReader)
//if err != nil { ....}, doesn't happen here
cipher, err := aes.NewCipher(symKey)
//if err != nil { ....}, doesn't happen here
byteData := make([]byte, len(encData))
cipher.Decrypt(byteData, encData)
fmt.Println("Dec: ", string(byteData))
//Outputs unrepresentable characters

      

Any idea?

+3


source to share


4 answers


Output CryptoJS.AES.encrypt is a CipherParams object containing a key, IV, optional salt, and ciphertext. The string you referenced was an OpenSSL compatible formatted string.

var encrypted = CryptoJS.AES.encrypt("Message", "Secret Passphrase");

alert(encrypted.key);        // 74eb593087a982e2a6f5dded54ecd96d1fd0f3d44a58728cdcd40c55227522223
alert(encrypted.iv);         // 7781157e2629b094f0e3dd48c4d786115
alert(encrypted.salt);       // 7a25f9132ec6a8b34
alert(encrypted.ciphertext); // 73e54154a15d1beeb509d9e12f1e462a0

alert(encrypted);            // U2FsdGVkX1+iX5Ey7GqLND5UFUoV0b7rUJ2eEvHkYqA= (OpenSSL-compatible format strategy)

      



The default encryption mode of CryptoJS is CBC. You must transmit the IV along with your symmetric key during the RSA exchange. With symmetric key, IV, and encrypted text byte arrays on the server, you can decrypt it in Go similarly to this:

c, err := aes.NewCipher(key)
cfbdec := cipher.NewCBCDecrypter(c, iv)
plaintext := make([]byte, len(ciphertext))
cfbdec.CryptBlock(plaintext, ciphertext)

      

+3


source


U2FsdGVkX19wbzVqqOr6U5dnuG34WyH+n1A4PX9Z+xBhY3bALGS7DOa/aphgnubc 

      

This data is base64

encoded, it looks something like this:

Salted__po5jSgm[!P8=Yacv,dj`

      



(note that there are under-represented characters on this line)

And that's exactly 32 bytes.

+2


source


Although not directly, you might find it helpful to take a look at https://github.com/dgryski/dkeyczar .

Its implementation of Go KeyCzar , an open source cryptography toolkit originally developed by members of the Google Security Team

Hope you can learn something from this project.

+1


source


There are probably several issues that we will need to address.

First, you need to make sure that you are giving the correct argument type for encryption (). It looks like you might have figured out in the comment that you need to do CryptoJS.enc.Hex.parse (symetricKeyHex), although your original post does not reflect this yet.

Second, you need to decide how you get or create the IV at both ends. CryptoJS can generate one if you use a passphrase, but you are trying to use the actual key, not the passphrase. This means that you will need to install the IV as you installed the key.

Finally, you will have to decide how you are going to transfer both the IV and the ciphertext. A typical and simple solution is to add an IV to the ciphertext, but actually anything that is easily serializable / unserializable will work fine. Just make sure that whatever format you choose is consistent at both ends.

0


source







All Articles