rubyopensslswift2aescryptoswift

Padding error with CryptoSwift and Ruby AES


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!


Solution

  • 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.