Nodejs aes 从 ios 应用程序数据解码

Nodejs aes decode from ios app data

做iOs应用的小伙伴们,用这种加密数据的方法:

- (NSData *)AES256DecryptWithKey:(NSString *)key
{
// 'key' should be 32 bytes for AES256, will be null-padded otherwise
char keyPtr[kCCKeySizeAES256+1]; // room for terminator (unused)
bzero( keyPtr, sizeof( keyPtr ) ); // fill with zeroes (for padding)

// fetch key data
[key getCString:keyPtr maxLength:sizeof( keyPtr ) encoding:NSUTF8StringEncoding];

NSUInteger dataLength = [self length];

//See the doc: For block ciphers, the output size will always be less than or 
//equal to the input size plus the size of one block.
//That's why we need to add the size of one block here
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc( bufferSize );

size_t numBytesDecrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt( kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
                                      keyPtr, kCCKeySizeAES256,
                                      NULL /* initialization vector (optional) */,
                                      [self bytes], dataLength, /* input */
                                      buffer, bufferSize, /* output */
                                      &numBytesDecrypted );

if( cryptStatus == kCCSuccess )
{
  //the returned NSData takes ownership of the buffer and will free it on deallocation
  return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
}

free( buffer ); //free the buffer
return nil;
 }

这显然是从互联网某处的代码示例中获取的。在四处挖掘时,我发现那段代码并不安全,但由于我们在数据库周围保存了一些数据,因此我们无法更改它。问题是我现在必须解码来自我的 nodejs 服务器的数据,它失败并显示错误代码:

  var ret = this._handle.final();
                     ^
  Error: error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt
  at Error (native)
  at Decipher.Cipher.final (crypto.js:202:26)

我目前的解密密码是:

var crypto = require('crypto')
  , key = new Buffer('keyhere')
  , decipher = crypto.createDecipher('aes128', key);
var decoded = decipher.update(encrypted, 'base64', 'utf8');
decoded += decipher.final('utf8');

编辑: 示例数据测试

//---obj c
NSString *key = @"testtesttesttesttesttesttesttest";
NSString *plainText = @"test text";

NSString *encr = [plainText AES256EncryptWithKey:key];
//gives 5SCMEm11AJz0zV5UFhA9ag==

//nodejs
var crypto = require('crypto')
  , key = new Buffer('testtesttesttesttesttesttesttest')
  , cipher = crypto.createCipher('aes-128-cbc', key)
  , plaintext = 'test text';
var encryptedPassword = cipher.update(plaintext, 'utf8', 'base64');
encryptedPassword += cipher.final('base64')
//gives 8a2aVfXJjyivuigCz1EhIA==

根据不完整的 nodejs 文档,您在 iOS (kCCKeySizeAES256) 上指定了一个 256 位密钥,在 nodejs (aes-128-cbc) 上指定了一个 128 位密钥。最好的猜测是您需要为 nodjs 指定 aes-256-cbc

具有 NUL iv 的 CCCrypt CBC 模式使用全零 iv。检查 nodejs 是否具有相同的默认值。最好完全指定所有参数而不依赖默认值。

在不使用类别的情况下,只需传递输入值,事情就更清晰也更容易测试。

实现(损坏的)算法的唯一方法是使用 forge js 节点模块并向其传递一个空填充 IV。

var key = 'testtesttesttesttesttesttesttest';
var iv = '[=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=][=10=]';
var cipher = forge.cipher.createCipher('AES-CBC', key);
cipher.start({iv: iv});
cipher.update(forge.util.createBuffer(plaintext));
cipher.finish();
var cipherText = forge.util.encode64(cipher.output.getBytes());