Reputation: 63
i already managed to share a random symetric key via rsa. However i fail to make aes-encryption work with it. Problem seems to be the salt and initialization vector, that cryptoJS uses.
First it's output is along the lines of:
U2FsdGVkX19wbzVqqOr6U5dnuG34WyH+n1A4PX9Z+xBhY3bALGS7DOa/aphgnubc
Googling for the reoccuring "U2FsdGVkX" or "cryptoJS.AES output" sadly is of no use.
On the other hand, golang's aes requires only a 32bit key and input of 32bit length each. Which means i have to somehow split the above into the corresponding blocks and figure out, how to create the 32bit key out of the secret key and the data above (which proably includes salt + init vector).
Sadly 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: After the Base64 response:
Thanks for the base64 input.
However i still don't manage to bring it to work.
Especially since the encoded string starts with "SALTED",
i believe, that there might be a problem.
Way i try to encode now:
Encoded on Client by:
var unencrypted = "{mail:test,password:test}"
var enc = CryptoJS.AES.encrypt(unencrypted, symKey)
On Server, the variables enc and symKey are the same as on 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?
Upvotes: 5
Views: 4357
Reputation: 194
Although, it don't directly but maybe you will find it useful to have a look at https://github.com/dgryski/dkeyczar.
Its Go implementation of KeyCzar, open source cryptographic toolkit originally developed by members of the Google Security Team
I hope you can learn something from this project
Upvotes: 1
Reputation: 2583
There are probably a few issues we'll need to work through.
First, you need to make sure you're supplying the correct type of arguments to encrypt(). It looks like you may have realized in a comment that you need to do CryptoJS.enc.Hex.parse(symetricKeyHex), though your original post doesn't reflect this yet.
Second, you need to decide how you're getting or creating the IV on both ends. CryptoJS can create one if you use a passphrase, but you're trying to use an actual key rather than a passphrase. That means you'll have to set the IV like you set the key.
Finally, you'll have to decide how you're going to transmit both the IV and the ciphertext. A typical and simple solution is to prepend the IV to the ciphertext, but really anything that's easily serializable/unserializable will work fine. Just make sure that whatever format you decide on is consistent on both ends.
Upvotes: 0
Reputation: 7638
The output of CryptoJS.AES.encrypt is a CipherParams object containing the key, IV, optional salt, and ciphertext. The string you were referencing was a 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)
CryptoJS' default encryption mode is CBC. You should pass the IV along with your symmetric key during your RSA-encrypted exchange. With the symmetric key, IV, and cipher text byte arrays on the server, you can decrypt it in Go similar to this:
c, err := aes.NewCipher(key)
cfbdec := cipher.NewCBCDecrypter(c, iv)
plaintext := make([]byte, len(ciphertext))
cfbdec.CryptBlock(plaintext, ciphertext)
Upvotes: 7
Reputation: 24858
U2FsdGVkX19wbzVqqOr6U5dnuG34WyH+n1A4PX9Z+xBhY3bALGS7DOa/aphgnubc
That data is base64
encoded, raw it looks something like this:
Salted__po5jSgm[!P8=Yacv,dj`
(note that there are unrepresentable characters in that string)
And this is exactly 32 bytes long.
Upvotes: 2