I am having a hard time getting CryptoSwift
to play nicely with Ruby's OpenSSL AES
My Swift code:
let key = ("12345678901234567890123456789012" as NSString).dataUsingEncoding(NSUTF8StringEncoding)?.arrayOfBytes() //32 chars because im testing AES 256
let iv = Cipher.randomIV(AES.blockSize)
let data = NSData(bytes: iv, length: Int(iv.count))
let ivstring = data.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0));
print(ivstring)
let message = "Hello World".dataUsingEncoding(NSUTF8StringEncoding)?.arrayOfBytes()
do
{
let encrypted = try AES(key: key!, iv: iv, blockMode: .CBC)?.encrypt(message!, padding: PKCS7())
let decrypted = try AES(key: key!, iv: iv, blockMode: .CBC)?.decrypt(encrypted!, padding: PKCS7())
let encData = NSData(bytes: encrypted!, length: Int(encrypted!.count))
let base64String: String = encData.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0));
let result = String(base64String)
print(result)
let decData = NSData(bytes: decrypted!, length: Int(decrypted!.count))
let result2 = NSString(data: decData, encoding: NSUTF8StringEncoding)
print(result2!)
}
catch
{
}
Which outputs:
7oR9lu+ROC7PW7bDqXcRxw==
XzZj2OTTbA8zaedeoVh0KA==
Hello World
Then over in Ruby I do:
key = "12345678901234567890123456789012"
iv = "7oR9lu+ROC7PW7bDqXcRxw=="
encrypted = "XzZj2OTTbA8zaedeoVh0KA=="
decipher = OpenSSL::Cipher::AES.new(256, :CBC)
decipher.decrypt
decipher.key = key
decipher.iv = iv
plain = decipher.update(encrypted) + decipher.final
The ruby code throws an error on the last line plain = decipher.update(encrypted) + decipher.final
stating:
OpenSSL::Cipher::CipherError
=================================================
> wrong final block length
I'm obviously not the most experienced person in encryption but any help you could give me would be very much appreciated!
You need to base 64 decode your data and iv before decrypting. You’re currently sending the base 64 encoded data directly through AES.
Don’t forget to strip the padding after decryption as well.