2

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!

jww
  • 97,681
  • 90
  • 411
  • 885
Deekor
  • 9,144
  • 16
  • 69
  • 121
  • It appears that you haven’t base 64 decoded your iv or data, you are feeding the base64 encoded strings directly to AES. Does adding a couple of `Base64.decode(...)` fix things? – matt Oct 09 '15 at 19:37
  • @matt that solved it! `Base64.decode64(...)` on both the `iv` and `encrypted` did the trick. Do you want to post an answer I can accept? – Deekor Oct 09 '15 at 20:06

1 Answers1

1

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.

matt
  • 78,533
  • 8
  • 163
  • 197
  • *"Don’t forget to strip the padding after decryption as well...."* - as far as I know, libraries like OpenSSL, Botan, and Crypto++ strip the padding. GnuPG is unique in that it does not strip the padding during decryption. – jww Oct 09 '15 at 22:32
  • @jww Ya I didn't need to do that. – Deekor Oct 09 '15 at 22:55
  • @jww That would makes sense. I’m working through some [crypto exercises](http://cryptopals.com/) at the moment, so have to remember to strip padding myself. – matt Oct 09 '15 at 23:14