在 Swift 3 中使用 CommonCrypto 解密 DES
Decrypting DES with CommonCrypto in Swift 3
我想用 CommonCrypto 解密 DES 加密的字符串。
我已经将带桥接的 CommonCrypto Header 导入到我的项目中。
通过反复尝试,我设法调用了 CCCrypt 函数,它甚至 returns 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) ?? "???"
}
此代码现在 returns 是正确的结果。
只剩下一个小问题了:返回的结果String现在看起来像下面这样:"encryptedString\u{08}\u{08}\u{08}\u{08}\u{08}\u{08}\u{08}\u{08}"
我怎样才能去掉这最后 8 个字节?
我试图像这样初始化我的结果:
var result = Data(count: data.count - kCCBlockSizeDES)
但是我得到了一个 kCCBufferTooSmall 错误。
更新2:
我现在使用 CCOptions(kCCOptionPKCS7Padding|kCCOptionECBMode)
但这只是将“\u{08}”字符更改为“\0”字符。所以现在我只需在返回结果字符串上调用 .trimmingCharacters(in: CharacterSet.controlCharacters)
即可。
将字符串加密或解密为字符串时,需要 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。)
还有一个,当你想接收数据到mutable(var
)Data
时,设置count
(不仅仅是capacity
)的Data
. (#2 和#3)
已更新
而且,正如 zaph 所说,您需要为 CBC 模式(默认)指定 IV 或使用 ECB 模式(#4)。
你的代码应该是这样的:
if
let key = "12345678".data(using: .utf8),
let data = Data(base64Encoded: encrypted, options: .ignoreUnknownCharacters) //<-#1
{
var numBytesDecrypted: size_t = 0
var result = Data(count: data.count) //<-#2
let err = result.withUnsafeMutableBytes {resultBytes in
data.withUnsafeBytes {dataBytes in
key.withUnsafeBytes {keyBytes in
CCCrypt(CCOperation(kCCDecrypt), CCAlgorithm(kCCAlgorithmDES), CCOptions(kCCOptionPKCS7Padding|kCCModeECB), keyBytes, kCCKeySizeDES, nil, dataBytes, data.count, resultBytes, result.count, &numBytesDecrypted) //<-#4
}
}
}
if err != CCCryptorStatus(kCCSuccess) {
NSLog("Decryption failed! Error: \(err.description)")
}
print(numBytesDecrypted)
result.count = numBytesDecrypted //<-#3
print(result as NSData) //`as NSData` is good for debugging.
return String(data: result, encoding: .utf8) ?? "???"
}
return "???"
我想用 CommonCrypto 解密 DES 加密的字符串。
我已经将带桥接的 CommonCrypto Header 导入到我的项目中。
通过反复尝试,我设法调用了 CCCrypt 函数,它甚至 returns 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) ?? "???"
}
此代码现在 returns 是正确的结果。 只剩下一个小问题了:返回的结果String现在看起来像下面这样:"encryptedString\u{08}\u{08}\u{08}\u{08}\u{08}\u{08}\u{08}\u{08}"
我怎样才能去掉这最后 8 个字节?
我试图像这样初始化我的结果:
var result = Data(count: data.count - kCCBlockSizeDES)
但是我得到了一个 kCCBufferTooSmall 错误。
更新2:
我现在使用 CCOptions(kCCOptionPKCS7Padding|kCCOptionECBMode)
但这只是将“\u{08}”字符更改为“\0”字符。所以现在我只需在返回结果字符串上调用 .trimmingCharacters(in: CharacterSet.controlCharacters)
即可。
将字符串加密或解密为字符串时,需要 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。)
还有一个,当你想接收数据到mutable(var
)Data
时,设置count
(不仅仅是capacity
)的Data
. (#2 和#3)
已更新 而且,正如 zaph 所说,您需要为 CBC 模式(默认)指定 IV 或使用 ECB 模式(#4)。
你的代码应该是这样的:
if
let key = "12345678".data(using: .utf8),
let data = Data(base64Encoded: encrypted, options: .ignoreUnknownCharacters) //<-#1
{
var numBytesDecrypted: size_t = 0
var result = Data(count: data.count) //<-#2
let err = result.withUnsafeMutableBytes {resultBytes in
data.withUnsafeBytes {dataBytes in
key.withUnsafeBytes {keyBytes in
CCCrypt(CCOperation(kCCDecrypt), CCAlgorithm(kCCAlgorithmDES), CCOptions(kCCOptionPKCS7Padding|kCCModeECB), keyBytes, kCCKeySizeDES, nil, dataBytes, data.count, resultBytes, result.count, &numBytesDecrypted) //<-#4
}
}
}
if err != CCCryptorStatus(kCCSuccess) {
NSLog("Decryption failed! Error: \(err.description)")
}
print(numBytesDecrypted)
result.count = numBytesDecrypted //<-#3
print(result as NSData) //`as NSData` is good for debugging.
return String(data: result, encoding: .utf8) ?? "???"
}
return "???"