Nodejs从ios app数据解码

时间:2015-03-19 11:26:13

标签: ios node.js encryption

执行iOs app的人使用这种加密数据的方法:

- (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==

2 个答案:

答案 0 :(得分:1)

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

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

在不使用Categories的情况下,只需传递输入值,就可以更清晰,更容易地进行测试。

答案 1 :(得分:0)

实现(破坏)算法的唯一方法是使用伪造js节点模块并将其传递给空填充IV。

var key = 'testtesttesttesttesttesttesttest';
var iv = '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0';
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());