简体   繁体   English

aesEncrypt会产生不同的结果

[英]aesEncrypt produces different results

I'm trying to encrypt a string in Swift 3, and my encryption is giving different output every time. 我正在尝试加密Swift 3中的字符串,我的加密每次都会提供不同的输出。 Why is that? 这是为什么? (I have tried similar encryption in python, and the encrypted output is always the same). (我在python中尝试过类似的加密,加密输出总是一样的)。

Here is my Swift 3 aesEncrypt function: 这是我的Swift 3 aesEncrypt功能:

func aesEncrypt(key:String, iv:Array<Any>, options:Int = kCCOptionPKCS7Padding) -> String? {
    if let keyData = sha256(string:key),
        let data = self.data(using: String.Encoding.utf8),
        let cryptData    = NSMutableData(length: Int((data.count)) + kCCBlockSizeAES128) {

        let keyLength              = size_t(kCCKeySizeAES128)
        let operation: CCOperation = UInt32(kCCEncrypt)
        let algorithm:  CCAlgorithm = UInt32(kCCAlgorithmAES128)
        let options:   CCOptions   = UInt32(options)

        var numBytesEncrypted :size_t = 0

        let cryptStatus = CCCrypt(operation,
                                  algorithm,
                                  options,
                                  (keyData as NSData).bytes, keyLength,
                                  iv,
                                  (data as NSData).bytes, data.count,
                                  cryptData.mutableBytes, cryptData.length,
                                  &numBytesEncrypted)
        // ADDED PRINT STATEMENTS 
        print("keyData")
        print(keyData)
        print("\(keyData as NSData)")
        print("iv")
        print(iv)
        var hex_iv = toHexString(arr: iv as! [UInt8])
        print(hex_iv)
        print("data")
        print(data)
        print("\(data as NSData)")

        print("encryption: cryptdata")
        print(cryptData)

        print("encryption: num bytes encrypted")
        print(numBytesEncrypted)

        if UInt32(cryptStatus) == UInt32(kCCSuccess) {
            cryptData.length = Int(numBytesEncrypted)
            let base64cryptString = cryptData.base64EncodedString(options: .lineLength64Characters)
            return base64cryptString
        }
        else {
            return nil
        }
    }
    return nil
}

When I try to run the following code with initial_string = "hello", I get different encrypted output strings every time. 当我尝试使用initial_string =“hello”运行以下代码时,每次都会得到不同的加密输出字符串。

let iv [UInt8](repeating: 0, count: 16)
let key = "sample_key"
let initial_string = "hello"

let encryptedString = initial_string.aesEncrypt(key: key, iv: iv)
print("Encrypted string")
print(encryptedString)

sample output from running code with "hello" string first time: 第一次使用“hello”字符串运行代码的示例输出:

keyData
32 bytes
<d5a78c66 e9b3ed40 b3a92480 c732527f 1a919fdc f68957d2 b7e9218f 6221085d>
iv
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
data
5 bytes
<68656c6c 6f>
encryption: cryptdata
<b17d67fc 26e3f316 6a2bdfbf 9d387c2d 00000000 00>
encryption: num bytes encrypted
16
Encrypted string
Optional("sX1n/Cbj8xZqK9+/nTh8LQ==")

sample output from running code with "hello" string second time: 第二次使用“hello”字符串运行代码的示例输出:

keyData
32 bytes
<d5a78c66 e9b3ed40 b3a92480 c732527f 1a919fdc f68957d2 b7e9218f 6221085d>
iv
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
data
5 bytes
<68656c6c 6f>
encryption: cryptdata
<01b9f69b 45deb31d eda46c2d dc9ad9e8 00000000 00>
encryption: num bytes encrypted
16
Encrypted string
Optional("Abn2m0Xesx3tpGwt3JrZ6A==")

Can you tell me why the output is different every time for the same key, iv, and string? 你能告诉我为什么每次输出相同的键,iv和字符串的输出都不同吗? Thanks! 谢谢!

Disclaimer: I can't run the question code. 免责声明:我无法运行问题代码。 Among other things it is not complete, the extension declaration is missing. 除其他事项外,它还没有完整,缺少扩展声明。 Also it seems to be Swift 2 code, this needs to be at least updated to Swift 3. 它似乎也是Swift 2代码,这需要至少更新到Swift 3。

encryption: cryptdata 加密:cryptdata
<01b9f69b 45deb31d eda46c2d dc9ad9e8 00000000 00> <01b9f69b 45deb31d eda46c2d dc9ad9e8 00000000 00>

Is completely wrong, it is even the wrong length Encrypted data will be a multiple of the block size. 完全错误,它甚至是错误的长度加密数据将是块大小的倍数。

With PKCS#7 padding and CBC mode the encrypted result should be: C99A30D8DA44968418E8B66F42790216. 使用PKCS#7填充和CBC模式时,加密结果应为:C99A30D8DA44968418E8B66F42790216。 See Cyyptomathic AES CALCULATOR . 参见Cyyptomathic AES CALCULATOR Note the 0b0b0b0b0b0b0b0b0b0b0b is the PKCS#7 padding. 注意0b0b0b0b0b0b0b0b0b0b0b是PKCS#7填充。

Here is an example in Swift 3, this is not production code, it is missing error handling at a minimum. 这是Swift 3中的一个示例,这不是生产代码,它至少缺少错误处理。

func SHA256(string:String) -> Data {
    let data = string.data(using:.utf8)!
    var hashData = Data(count: Int(CC_SHA256_DIGEST_LENGTH))

    _ = hashData.withUnsafeMutableBytes {digestBytes in
        data.withUnsafeBytes {messageBytes in
            CC_SHA256(messageBytes, CC_LONG(data.count), digestBytes)
        }
    }
    return hashData
}

func aesCBCEncrypt(data:Data, keyData:Data, ivData:Data) -> Data {
    let cryptLength = size_t(kCCBlockSizeAES128 + data.count + kCCBlockSizeAES128)
    var cryptData   = Data(count:cryptLength)
    var numBytesEncrypted :size_t = 0

    let cryptStatus = cryptData.withUnsafeMutableBytes {cryptBytes in
        data.withUnsafeBytes {dataBytes in
            keyData.withUnsafeBytes {keyBytes in
                ivData.withUnsafeBytes {ivBytes in
                    CCCrypt(CCOperation(kCCEncrypt),
                            CCAlgorithm(kCCAlgorithmAES),
                            CCOptions(kCCOptionPKCS7Padding),
                            keyBytes, keyData.count,
                            ivBytes,
                            dataBytes, data.count,
                            cryptBytes, cryptLength,
                            &numBytesEncrypted)
                }}}}

    cryptData.count = (cryptStatus == kCCSuccess) ? numBytesEncrypted : 0

    return cryptData;
}


let keyString = "sample_key"
let keyData = SHA256(string:keyString)
print("keyString: \(keyString)")
print("keyData:   \(hexEncode(keyData))")

let clearData = hexDecode("68656c6c6f")
// let keyData   = hexDecode("d5a78c66e9b3ed40b3a92480c732527f1a919fdcf68957d2b7e9218f6221085d")
let ivData    = hexDecode("00000000000000000000000000000000")

print("clearData: \(hexEncode(clearData))")
print("keyData:   \(hexEncode(keyData))")
print("ivData:    \(hexEncode(ivData))")

let cryptData = aesCBCEncrypt(data:clearData, keyData:keyData, ivData:ivData)
print("cryptData: \(hexEncode(cryptData))")

Output: 输出:

keyString: sample_key  
keyData:   d5a78c66e9b3ed40b3a92480c732527f1a919fdcf68957d2b7e9218f6221085d

clearData: 68656c6c6f
keyData:   d5a78c66e9b3ed40b3a92480c732527f1a919fdcf68957d2b7e9218f6221085d
ivData:    00000000000000000000000000000000
cryptData: c99a30d8da44968418e8b66f42790216

you see that IV? 你看到IV吗? that is initialization vector, that functions as a counter to make you encryption different each time, making it more secure and hard to break. 这是初始化向量,用作计数器,使您每次加密都不同,使其更安全,更难以破解。 so basically your code is working fine, but to decrypt it correctly, the receiver can not act only by having Key , but needs IV also 所以基本上你的代码工作正常,但要正确解密,接收器不能只通过拥有Key,但也需要IV

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 SVM sklearn上的随机种子产生不同的结果 - Random seed on SVM sklearn produces different results Jython随机模块为cpython产生不同的结果 - Jython random module produces different results to cpython Matlab和Python对PCA产生不同的结果 - Matlab and Python produces different results for PCA 使用append方法和+运算符追加列表会在Python中产生不同的结果吗? - Appending to list using append method and + operator produces different results in Python? Leetcode 322:用 2 种编程语言找硬币会产生 2 种不同的结果 - Leetcode 322: Coin change with 2 programming languages produces 2 different results 连续两次打印 DictReader 列表会产生不同的结果 - Printing list of DictReader twice in a row produces different results 使用char指针函数和std :: string调用线程会产生不同的结果 - Calling thread with char pointer function and std::string produces different results 在 cmd 中手动运行命令会产生与 Python 不同的结果 - Manually running command in cmd produces different results than with Python 为什么使用 PIL 和 pytorch 对图像进行双线性缩放会产生不同的结果? - Why bilinear scaling of images with PIL and pytorch produces different results? 如果我在训练期间执行验证,Pytorch 会产生不同的结果吗? - Pytorch produces different results if I perform validation or not during the training?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM