在Swift 3中用CommonCrypto解密DES

时间:2017-05-18 10:08:30

标签: swift xcode encryption swift3 commoncrypto

我想用CommonCrypto解密DES加密的字符串。

我已经将带有桥接头的CommonCrypto导入到我的项目中。

通过尝试和错误我设法调用CCCrypt函数,它甚至返回kCCSuccess。

但之后我的结果仍然是空的。

这是我的代码:

if let key = "12345678".data(using: .utf8), let data = "inMyOriginalCodeYouWouldSeeADESEncryptedStringHere/ahw==".data(using: .utf8) {
        var numBytesDecrypted: size_t = 0
        var result = Data(capacity: data.count)

        let err = result.withUnsafeMutableBytes {resultBytes in
            data.withUnsafeBytes {dataBytes in
                key.withUnsafeBytes {keyBytes in
                    CCCrypt(CCOperation(kCCDecrypt), CCAlgorithm(kCCAlgorithmDES), CCOptions(kCCOptionPKCS7Padding), keyBytes, kCCKeySizeDES, nil, dataBytes, data.count, resultBytes, data.count, &numBytesDecrypted)
                }
            }
        }

        if err != CCCryptorStatus(kCCSuccess) {
            NSLog("Decryption failed! Error: \(err.description)")
        }

        print(numBytesDecrypted)
        print(result)

        return String(data: result, encoding: .utf8) ?? "???"
    }
    return "???"
}

目前两条印刷线的输出为:

56
0 bytes

更新

根据接受的答案更正代码:

let encrypted = "inMyOriginalCodeYouWouldSeeADESEncryptedStringHere/ahw=="
if let key = "12345678".data(using: .utf8), let data = Data(base64Encoded: encrypted) {
        var numBytesDecrypted: size_t = 0
        var result = Data(count: data.count)

        let err = result.withUnsafeMutableBytes {resultBytes in
            data.withUnsafeBytes {dataBytes in
                key.withUnsafeBytes {keyBytes in
                    CCCrypt(CCOperation(kCCDecrypt), CCAlgorithm(kCCAlgorithmDES), CCOptions(kCCOptionECBMode), keyBytes, kCCKeySizeDES, nil, dataBytes, data.count, resultBytes, data.count, &numBytesDecrypted)
                }
            }
        }

        if err != CCCryptorStatus(kCCSuccess) {
            NSLog("Decryption failed! Error: \(err.description)")
        }

        return String(data: result, encoding: .utf8) ?? "???"
}

此代码现在返回正确的结果。 只剩下一个小问题:返回的结果字符串现在如下所示:" encryptedString \ u {08} \ u {08} \ u {08} \ u {08} \ u {08} \ u {08} \∪{08} \∪{08}"

如何摆脱最后8个字节?

我试图像这样初始化我的结果:

var result = Data(count: data.count - kCCBlockSizeDES)

但是我得到了一个kCCBufferTooSmall错误。

UPDATE2:

我现在使用CCOptions(kCCOptionPKCS7Padding|kCCOptionECBMode),但这只改变了" \ u {08}"字符到" \ 0"字符。所以现在我只需在结果字符串上调用.trimmingCharacters(in: CharacterSet.controlCharacters),然后再返回它。

1 个答案:

答案 0 :(得分:2)

当您从String加密或解密为String时,您需要3个步骤,因为现代加密算法仅适用于二进制数据。

编码:

[original String]
↓(encode in UTF-8)
[original binary]
↓(encrypt)
[encrypted binary]
↓(encode in base64)
[encrypted String]

(我猜你有一个base64编码的字符串作为加密字符串中的==建议。)

因此,在解码时,您需要反过来执行所有这些步骤。

解码:

[encrypted String]
↓(decode in base64)
[encrypted binary]
↓(decrypt)
[original binary]
↓(decode in UTF-8)
[original String]

您正在以错误的方式进行解码的第一步。 (参见下面代码的第1部分。)

另外,当您想要将数据接收到可变(varData时,请设置count的{​​{1}}(不仅capacity)。 (#2和#3)

<强>已更新 并且,如zaph所述,您需要为CBC模式指定IV(默认)或使用ECB模式(#4)。

您的代码应该是这样的:

Data