Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS Swift 4:How to perform encryption/decryption with DES-ECB-PKCS5Padding?

I want to perform encryption/decryption with DES-ECB-PKCS5Padding in iOS Swift.

I have some code from Server Side (most probably in ActionScript) to help which is as follows:

private static const type:String='simple-des-ecb';

public static function encrypt(txt:String, salt:String): String
{
    var key:ByteArray = Hex.toArray(Hex.fromString(salt));
    var data:ByteArray = Hex.toArray(Hex.fromString(txt));
    var pad:IPad = new PKCS5;
    var mode:ICipher = Crypto.getCipher(type, key, pad);
    pad.setBlockSize(mode.getBlockSize());
    mode.encrypt(data);
    data.position = 0;
    return Base64.encodeByteArray(data);
}

public static function decrypt(txt:String, salt:String): String
{
    var key:ByteArray = Hex.toArray(Hex.fromString(salt));
    var data:ByteArray = Base64.decodeToByteArray(txt);
    var pad:IPad = new PKCS5;
    var mode:ICipher = Crypto.getCipher(type, key, pad);
    pad.setBlockSize(mode.getBlockSize());
    try
    {
        mode.decrypt(data);
    }
    catch (e:Error)
    {
        trace(e.message);
        trace(e.getStackTrace());
    }
    return Hex.toString(Hex.fromArray(data));
}

I have tried to reciprocate the above functions in Swift, but I'm unable to get desired results

My Swift code goes as follows:

func encrypt(text: String, salt: String) -> String {

    let strHexKey = hexFromString(string: salt)
    let key = strHexKey.hexaBytes

    let strHexData = hexFromString(string: text)
    let data = strHexData.hexaBytes

    let cryptor = Cryptor(operation: .encrypt, algorithm: .des, options: .PKCS7Padding, key: key, iv: Array<UInt8>())
    let cipherText = cryptor.update(byteArray: data)?.final()

    let strBase64 = cipherText!.data.base64EncodedString()

    return strBase64

}

func decrypt(text: String, salt: String) -> String {

    let strHexKey = hexFromString(string: salt)
    let key = arrayFrom(hexString: strHexKey)

    let data = text.fromBase64()?.data(using: .utf8)

    let cryptor = Cryptor(operation: .decrypt, algorithm: .des, options: .PKCS7Padding, key: key, iv: Array<UInt8>())
    let cipherText = cryptor.update(data: data!)!.final()

    return (cipherText?.hexa)!

}

I have been using https://github.com/iosdevzone/IDZSwiftCommonCrypto for Cryptor Library.

like image 403
Vaibhav Jhaveri Avatar asked Mar 05 '23 20:03

Vaibhav Jhaveri


1 Answers

Swift Code

A conversion of the ActionScript code to Swift could look like this:

func encrypt(text: String, salt: String) -> String? {
    let key = Array(salt.utf8)
    let bytes = Array(text.utf8)
    let cryptor = Cryptor(operation: .encrypt, algorithm: .des, options: [.ECBMode, .PKCS7Padding], key: key, iv:[UInt8]())
    if let encrypted = cryptor.update(byteArray: bytes)?.final() {
        return Data(encrypted).base64EncodedString()
    }
    return nil
}

func decrypt(text: String, salt: String) -> String? {
    let key = Array(salt.utf8)
    let bytes = [UInt8](Data(base64Encoded: text)!)
    let cryptor = Cryptor(operation: .decrypt, algorithm: .des, options: [.ECBMode, .PKCS7Padding], key: key, iv:[UInt8]())
    if let decrypted = cryptor.update(byteArray: bytes)?.final() {
        return String(bytes: decrypted, encoding: .utf8)
    }
    return nil
}

Quick Test

In the comments you used as a test case with text [email protected] and salt: 123456. This would be called like this:

let salt = "123456"
if let encrypted = self.encrypt(text: "[email protected]", salt: salt) {
    print ("encrypted: " + encrypted)
    if let decrypted = self.decrypt(text: encrypted, salt: salt) {
        print ("decrypted: " + decrypted)
    }
}

The correct output would be:

encrypted: +rptz3Ss8zh2j0VXN7CICsi2jkzYoAPx
decrypted: [email protected]

I don't know where you got your result eLnJvMUKApg= from, but it's wrong. Also the ActionScript code you are quoting in your question would give the result +rptz3Ss8zh2j0VXN7CICsi2jkzYoAPx.

Compare with ActionScript

Flex

You can download the free flex sdk from here:

https://download.macromedia.com/pub/flex/sdk/flex_sdk_4.6.zip

as3crypto Library

The ActionScript quoted seems to use a library called as3crypto, which can be downloaded from here:

https://code.google.com/archive/p/as3crypto/

Flex depends on an installed Java environment. It doesn't seem to work with the latest version of Java out of the box, but you can use Java 1.6 for example.

You can create a small ActionScript program that calls the as3crypto routines. If the file is called e.g. Main.as, it can be compiled with the following command:

flex_sdk_4.6/bin/mxmlc Main.as

The output is then a Main.swf file, which can be executed with the Flash plugin in a browser.

Result

The result of the ActionScript code is the same as the Swift code, see here this screenshot:

Comparison with ActionScript Code

like image 92
Stephan Schlecht Avatar answered Apr 28 '23 15:04

Stephan Schlecht