【问题标题】:Encrypt and Decrypt iOS/Node.js Security Inquiry加密和解密 iOS/Node.js 安全查询
【发布时间】:2015-10-13 09:49:15
【问题描述】:

我目前在两个平台上都使用 AES128,我的代码来自 answer
注意:我稍微更改了代码以偏离使用 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 <CommonCrypto/CommonCrypto.h>
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"
}

然后使用从这两个场景生成的密钥和密码解密两个密码?

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

基本上,我对自己的加密模型是否有正确的想法感到困惑。

感谢您的帮助。

【问题讨论】:

  • 您真的不应该在您的应用程序中硬编码密码或编码密钥。这不提供实际的安全性,只是混淆。您可以在应用程序中对 RSA 公钥进行硬编码,并通过该公钥与服务器建立一个临时密钥。如果您使用带有证书固定的 TLS,那就更好了。

标签: ios node.js encryption sha256 password-encryption


【解决方案1】:

通常使用随机盐并将其添加到加密数据中。也很常见的是在 PBKDF2 迭代计数之前加上版本号,以帮助面向未来。最后,跳过 iv 会降低对第一个块的保护,您可以考虑使用身份验证哈希。

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

注意事项:
我不了解盐的 CC_SHA256,那应该没有必要。

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

【讨论】:

  • 所以我应该将带有加密密码的密钥存储在用户注册的数据库中。然后,每当用户登录时,都会使用另一个随机盐重新加密,发送新密钥和新密码,并与旧密钥和旧密码进行比较。这个对吗?我可能会决定稍后再添加一个 iv,我只是想快速起步。
  • 我还没有真正检查过db部分,我来看看。如果您要“快速启动”,请确保为加密数据添加版本号,否则您将被锁定。考虑是否“真的”稍后会有更新。
  • 所以你的意思是 key = "1.0" + key;?
  • 否,在 Base64 编码之前添加到加密数据。
  • 你能帮我弄清楚为什么我的 iOS 和 Node 的加密数据不同吗?它们都具有相同的密钥、散列和解密值。但是加密的数据是不同的,但我很确定我在两者中都使用了 AES 128。 IOS:vfOzya0yV9G5hLHeSh3R1g= 和节点:8fd7cd38dd715f9269f9eb40ecb43ab9
猜你喜欢
  • 2015-10-31
  • 1970-01-01
  • 2015-02-27
  • 2021-05-06
  • 1970-01-01
  • 1970-01-01
  • 2014-11-20
  • 2019-01-07
  • 1970-01-01
相关资源
最近更新 更多