Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
160 views
in Technique[技术] by (71.8m points)

javascript - Encrypt iOS and Decrypt Node.js AES

I have searched high and low for a solution which and encrypt on Node.js server and Objective-C client, and vise versa using AES (or other if appropriate)

I am relatively new to cryptography, and understanding why my encrypted text is different in each language is beyond my knowledge.

This is what I have so far:

Node.js crypto methods Using this CryptoJS Library - node-cryptojs-aes

var node_cryptojs = require("node-cryptojs-aes");
var CryptoJS = node_cryptojs.CryptoJS;

    var textToEncrypt = 'Hello';
var key_clear = 'a16byteslongkey!';

//encrypted + decrypted

var encrypted = CryptoJS.AES.encrypt(clearText, key_clear, { iv: null });
var decrypted = CryptoJS.AES.decrypt(encrypted, key_clear, { iv: null });

//Outputs   
    console.log("encrypted: " + encrypted);     //encrypted: U2FsdGVkX1/ILXOjqIw2Vvz6DzRh1LMHgEQhDm3OunY=
console.log("decrypted: " + decrypted.toString(CryptoJS.enc.Utf8));   // decrypted: Hello

Objective-C crypto methods Using AESCrypt library

NSString* textToEncrypt = @"Hello";

// encrypt
NSString* encryptedText = [AESCrypt encrypt:textToEncrypt password:@"a16byteslongkey!"];

// decrypt
NSString* decryptedText = [AESCrypt decrypt:encryptedText password:@"a16byteslongkey!"];

// output
NSLog(@"Text to encrypt: %@", textToEncrypt);    // Text to encrypt: Hello
NSLog(@"Encrypted text: %@", encryptedText);     // Encrypted text: wY80MJyxRRJdE+eKw6kaIA==
NSLog(@"Decrypted text: %@", decryptedText);     // Decrypted text: Hello

I've been scratching my head for ages and tried everything I can think of. Can show underlying crypto methods from the libraries if required. There is SHAR256 hash applied to the key in AESCrypt library but I have removed this, and think there is some missmatch with the string encoding.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I'm posting this here because there are bound to be others trying to interop Node.js and iOS. Everyone seems to get hung up on keeping everything in the correct structures, buffers, strings etc. I know I did. So here is a step-by-step process to creating a key, creating an iv, encrypting, decrypting and placing in base64 for easy transfer:

JavaScript (Node.js using the CryptoJS module)

    // Generate key from password and salt using SHA256 to hash and PDKDF2 to harden
    var password = "1234567890123456";
    var salt = "gettingsaltyfoo!";
    var hash = CryptoJS.SHA256(salt);
    var key = CryptoJS.PBKDF2(password, hash, { keySize: 256/32, iterations: 1000 });
    console.log("Hash :",hash.toString(CryptoJS.enc.Base64));
    console.log("Key :",key.toString(CryptoJS.enc.Base64));

    // Generate a random IV
    var iv = CryptoJS.lib.WordArray.random(128/8);
    console.log("IV :",iv.toString(CryptoJS.enc.Base64));

    // Encrypt message into base64
    var message = "Hello World!";
    var encrypted = CryptoJS.AES.encrypt(message, key, { iv: iv });
    var encrypted64 = encrypted.ciphertext.toString(CryptoJS.enc.Base64);
    console.log("Encrypted :",encrypted64);

    // Decrypt base64 into message again
    var cipherParams = CryptoJS.lib.CipherParams.create({ ciphertext: CryptoJS.enc.Base64.parse(encrypted64) });
    var decrypted = CryptoJS.AES.decrypt(cipherParams, key, { iv: iv }).toString(CryptoJS.enc.Utf8);
    console.log("Decrypted :",decrypted);

iOS SDK using CommonCrypto

    // Generate key from password and salt using SHA256 to hash and PDKDF2 to harden
    NSString* password = @"1234567890123456";
    NSString* salt = @"gettingsaltyfoo!";
    NSMutableData* hash = [NSMutableData dataWithLength:CC_SHA256_DIGEST_LENGTH];
    NSMutableData* key = [NSMutableData dataWithLength:CC_SHA256_DIGEST_LENGTH];
    CC_SHA256(salt.UTF8String, (CC_LONG)strlen(salt.UTF8String), hash.mutableBytes);
    CCKeyDerivationPBKDF(kCCPBKDF2, password.UTF8String, strlen(password.UTF8String), hash.bytes, hash.length, kCCPRFHmacAlgSHA1, 1000, key.mutableBytes, key.length);
    NSLog(@"Hash : %@",[hash base64EncodedStringWithOptions:0]);
    NSLog(@"Key : %@",[key base64EncodedStringWithOptions:0]);

    // Generate a random IV (or use the base64 version from node.js)
    NSString* iv64 = @"ludWXFqwWeLOkmhutxiwHw==";       // Taken from node.js CryptoJS IV output
    NSData* iv = [[NSData alloc] initWithBase64EncodedString:iv64 options:0];
    NSLog(@"IV : %@",[iv base64EncodedStringWithOptions:0]);

    // Encrypt message into base64
    NSData* message = [@"Hello World!" dataUsingEncoding:NSUTF8StringEncoding];
    NSMutableData* encrypted = [NSMutableData dataWithLength:message.length + kCCBlockSizeAES128];
    size_t bytesEncrypted = 0;
    CCCrypt(kCCEncrypt,
            kCCAlgorithmAES128,
            kCCOptionPKCS7Padding,
            key.bytes,
            key.length,
            iv.bytes,
            message.bytes, message.length,
            encrypted.mutableBytes, encrypted.length, &bytesEncrypted);
    NSString* encrypted64 = [[NSMutableData dataWithBytes:encrypted.mutableBytes length:bytesEncrypted] base64EncodedStringWithOptions:0];
    NSLog(@"Encrypted : %@",encrypted64);

    // Decrypt base 64 into message again
    NSData* encryptedWithout64 = [[NSData alloc] initWithBase64EncodedString:encrypted64 options:0];
    NSMutableData* decrypted = [NSMutableData dataWithLength:encryptedWithout64.length + kCCBlockSizeAES128];
    size_t bytesDecrypted = 0;
    CCCrypt(kCCDecrypt,
            kCCAlgorithmAES128,
            kCCOptionPKCS7Padding,
            key.bytes,
            key.length,
            iv.bytes,
            encryptedWithout64.bytes, encryptedWithout64.length,
            decrypted.mutableBytes, decrypted.length, &bytesDecrypted);
    NSData* outputMessage = [NSMutableData dataWithBytes:decrypted.mutableBytes length:bytesDecrypted];
    NSString* outputString = [[NSString alloc] initWithData:outputMessage encoding:NSUTF8StringEncoding];
    NSLog(@"Decrypted : %@",outputString);

The output should be the same

    /*
        Hash : AEIHWLT/cTUfXdYJ+oai6sZ4tXlc4QQcYTbI9If/Moc=
        Key : WdHhJ19dSBURBA25HZSpbCJ4KnNEEgwzqjgyTBqa3eg=
        IV : ludWXFqwWeLOkmhutxiwHw==
        Encrypted : D3JpubesPMgQTiXbaoxAIw==
        Decrypted : Hello World!
    */

Hopefully this saves someone else the time I've wasted :)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...