加密和解密iOS / Node.js安全查询

我目前正在两个平台上使用AES128,而我的代码来自这个答案
注意:我稍微更改了代码以避免使用IV,因为我认为这对于我的应用程序来说太过分了。

Node.js的:

var CryptoJS = require("crypto-js"); var crypto = require('crypto'); var password = "1234567890123456"; var salt = "gettingsaltyfoo!"; var hash = CryptoJS.SHA256(salt); var key = CryptoJS.PBKDF2(password, hash, { keySize: 256/32, iterations: 1000 }); var algorithm = 'aes128'; console.log(key.toString(CryptoJS.enc.Base64)); function encrypt(text){ var cipher = crypto.createCipher(algorithm,key.toString(CryptoJS.enc.Base64)); var crypted = cipher.update(text,'utf8','hex'); crypted += cipher.final('hex'); return crypted; } function decrypt(text){ var decipher = crypto.createDecipher(algorithm,key.toString(CryptoJS.enc.Base64)); var dec = decipher.update(text,'hex','utf8'); dec += decipher.final('utf8'); return dec; } 

iOS版:

  #import  NSString* password = @"1234567890123456"; NSString* salt = @"gettingsaltyfoo!"; -(NSString *)decrypt:(NSString*)encrypted64{ 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]); 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, NULL, 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); return outputString; } -(NSString *)encrypt:(NSString *)toEncrypt{ 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); NSData* message = [toEncrypt dataUsingEncoding:NSUTF8StringEncoding]; NSMutableData* encrypted = [NSMutableData dataWithLength:message.length + kCCBlockSizeAES128]; size_t bytesEncrypted = 0; CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, key.bytes, key.length, NULL, message.bytes, message.length, encrypted.mutableBytes, encrypted.length, &bytesEncrypted); NSString* encrypted64 = [[NSMutableData dataWithBytes:encrypted.mutableBytes length:bytesEncrypted] base64EncodedStringWithOptions:0]; NSLog(@"Encrypted : %@",encrypted64); return encrypted64; } 

我的问题:如果我像这样对盐进行硬编码可以吗? 我正在尝试加密和解密密码(var密码和NSString密码可能会被硬编码成某种东西)。 我在网上看到我需要在我的数据库中保存我的密码。 如果我硬编码我的盐是不行的,我如何将它从iOS发送到node.js并与盐一致? 我的iOS请求应该是这样的吗?

 { key:"someKeyGeneratedOnTheSpotWithRandomSalt", password:"somePasswordGeneratedFromKey" } 

在我的后端通过从数据库中提取这些字段来检查密码?

 { key:"someKeyGeneratedWhenTheUserFirstSignedUp", password:"somePasswordGeneratedFromTheOrginalKeyWhenUserFirstSignedUp" } 

然后使用两种方案生成的密钥和密码解密两个密码?

或者是否可以使用硬编码的盐,比如用户名,这样每个用户的密钥总是一样的?

基本上我很困惑我是否对我的加密模型有正确的想法。

谢谢你的帮助。

通常使用随机盐并将其添加到加密数据之前。 所有前缀PBKDF2迭代计数以及版本号有助于未来validation也是很常见的。 最后,跳过iv会减少对第一个块的保护,您可能会考虑使用身份validation哈希。

这类似于RNCryptor所做的。 有关加密消息的详细信息,请参阅RNCryptor-Spec-v3.md 。

笔记:
我不理解盐的CC_SHA256,这不应该是必要的。

NSData* outputMessage = [NSMutableData dataWithBytes:decrypted.mutableBytes length:bytesDecrypted];
是不必要的,只需设置decrypted的长度
decrypted.length = bytesDecrypted;
并使用decrypted代替outputMessage