AES256 问题使用 swift 5
AES256 Issue using swift 5
我正在使用 AES256
算法 CBC mode
和 pkc7
填充。我在 Node.js
中有后端。但是获得前 12 个随机字符。
这是我的 swift 代码:
func encrypt(data: Data, key: Data, iv: Data) throws -> Data? {
// Output buffer (with padding)
let outputLength = data.count + kCCBlockSizeAES128
var outputBuffer = Array<UInt8>(repeating: 0,
count: outputLength)
//var outputBuffer: [UInt8] = []
var numBytesEncrypted = 0
let status = CCCrypt(CCOperation(kCCEncrypt),
CCAlgorithm(kCCAlgorithmAES),
CCOptions(kCCOptionPKCS7Padding),
Array(key),
kCCKeySizeAES256,
Array(iv),
Array(data),
data.count,
&outputBuffer,
outputLength,
&numBytesEncrypted)
guard status == kCCSuccess else { return nil }
let outputBytes = iv + outputBuffer.prefix(numBytesEncrypted)
return Data(bytes: outputBytes)
}
没有填充怎么办?或者后端应该做什么?
您 post 编辑的内容没有任何问题,您可能只是在 Swift 和 node.js 之间的某个地方得到了一些不正确的参数。
首先,最好检查一下您是否可以在本地以相同的语言解密您加密的任何内容。使用您 post 编辑的屏幕截图中的信息(以后注意:还有 post 文本中的所有内容,从屏幕截图中输入 base 64 编码的数据比复制和粘贴要繁琐得多)。
在你的情况下,在 Swift 中,它看起来像这样:
import UIKit
import CommonCrypto
var key = "zewQjVQMGdoEJK0yHtLcbP3ZlHOKjERG"
// This is the ciphertext with the initialization vector prepended.
let base64String = "w93bonVuqtW22Drj4HtZ3zNtNSt+5OBMapGGHekLCFA="
var data = Data(base64Encoded: base64String)!
// Split out the initialization vector and ciphertext
var iv = data[0..<kCCBlockSizeAES128]
var ciphertext = data[kCCBlockSizeAES128..<data.count]
var outputLength = data.count
var outputBuffer = Array<UInt8>(repeating:0, count: outputLength)
var bytesDecrypted = 0
let status = CCCrypt(CCOperation(kCCDecrypt),
CCAlgorithm(kCCAlgorithmAES),
CCOptions(kCCOptionPKCS7Padding),
Array(key.utf8),
kCCKeySizeAES256,
Array(iv),
Array(ciphertext),
ciphertext.count,
&outputBuffer,
outputLength,
&bytesDecrypted
)
print(String(bytes: outputBuffer.prefix(bytesDecrypted), encoding: .utf8))
// Optional("gmail.com")
一旦您知道使用同一种语言一切正常,请尝试使用另一种语言。现在我对 node.js 了解不多,但是 line-by-line 通过 Swift 会导致这个:
const crypto = require('crypto')
let keyString = 'zewQjVQMGdoEJK0yHtLcbP3ZlHOKjERG'
let key = Buffer.from(keyString, 'utf8')
let base64String = 'w93bonVuqtW22Drj4HtZ3zNtNSt+5OBMapGGHekLCFA='
let ivPlusCiphertextBuffer = Buffer.from(base64String, 'base64')
// Split out the initialization vector and the ciphertext
let blockSize = 16 // Don't know how to get this in Node.js so hard-code it
let iv = ivPlusCiphertextBuffer.subarray(0, blockSize)
let ciphertext = ivPlusCiphertextBuffer.subarray(blockSize, ivPlusCiphertextBuffer.length)
let decryptor = crypto.createDecipheriv('aes-256-cbc', key, iv)
var plaintext = decryptor.update(ciphertext, 'binary', 'utf8')
plaintext += decryptor.final('utf8')
console.log(plaintext)
// gmail.com
因此,只要您将 Swift 例程的输出作为 node.js 例程的输入(类似于我上面的示例),您就可以开始了!
您可以在要共享的 负载之前和之后使用标签。该标签将是您的 headers.
喜欢<tag>string</tag>
所以如果你加密你会得到前 12 个随机字节
因此您需要忽略 **<tag>...</tag>**
之间以外的文本
我正在使用 AES256
算法 CBC mode
和 pkc7
填充。我在 Node.js
中有后端。但是获得前 12 个随机字符。
这是我的 swift 代码:
func encrypt(data: Data, key: Data, iv: Data) throws -> Data? {
// Output buffer (with padding)
let outputLength = data.count + kCCBlockSizeAES128
var outputBuffer = Array<UInt8>(repeating: 0,
count: outputLength)
//var outputBuffer: [UInt8] = []
var numBytesEncrypted = 0
let status = CCCrypt(CCOperation(kCCEncrypt),
CCAlgorithm(kCCAlgorithmAES),
CCOptions(kCCOptionPKCS7Padding),
Array(key),
kCCKeySizeAES256,
Array(iv),
Array(data),
data.count,
&outputBuffer,
outputLength,
&numBytesEncrypted)
guard status == kCCSuccess else { return nil }
let outputBytes = iv + outputBuffer.prefix(numBytesEncrypted)
return Data(bytes: outputBytes)
}
没有填充怎么办?或者后端应该做什么?
您 post 编辑的内容没有任何问题,您可能只是在 Swift 和 node.js 之间的某个地方得到了一些不正确的参数。
首先,最好检查一下您是否可以在本地以相同的语言解密您加密的任何内容。使用您 post 编辑的屏幕截图中的信息(以后注意:还有 post 文本中的所有内容,从屏幕截图中输入 base 64 编码的数据比复制和粘贴要繁琐得多)。
在你的情况下,在 Swift 中,它看起来像这样:
import UIKit
import CommonCrypto
var key = "zewQjVQMGdoEJK0yHtLcbP3ZlHOKjERG"
// This is the ciphertext with the initialization vector prepended.
let base64String = "w93bonVuqtW22Drj4HtZ3zNtNSt+5OBMapGGHekLCFA="
var data = Data(base64Encoded: base64String)!
// Split out the initialization vector and ciphertext
var iv = data[0..<kCCBlockSizeAES128]
var ciphertext = data[kCCBlockSizeAES128..<data.count]
var outputLength = data.count
var outputBuffer = Array<UInt8>(repeating:0, count: outputLength)
var bytesDecrypted = 0
let status = CCCrypt(CCOperation(kCCDecrypt),
CCAlgorithm(kCCAlgorithmAES),
CCOptions(kCCOptionPKCS7Padding),
Array(key.utf8),
kCCKeySizeAES256,
Array(iv),
Array(ciphertext),
ciphertext.count,
&outputBuffer,
outputLength,
&bytesDecrypted
)
print(String(bytes: outputBuffer.prefix(bytesDecrypted), encoding: .utf8))
// Optional("gmail.com")
一旦您知道使用同一种语言一切正常,请尝试使用另一种语言。现在我对 node.js 了解不多,但是 line-by-line 通过 Swift 会导致这个:
const crypto = require('crypto')
let keyString = 'zewQjVQMGdoEJK0yHtLcbP3ZlHOKjERG'
let key = Buffer.from(keyString, 'utf8')
let base64String = 'w93bonVuqtW22Drj4HtZ3zNtNSt+5OBMapGGHekLCFA='
let ivPlusCiphertextBuffer = Buffer.from(base64String, 'base64')
// Split out the initialization vector and the ciphertext
let blockSize = 16 // Don't know how to get this in Node.js so hard-code it
let iv = ivPlusCiphertextBuffer.subarray(0, blockSize)
let ciphertext = ivPlusCiphertextBuffer.subarray(blockSize, ivPlusCiphertextBuffer.length)
let decryptor = crypto.createDecipheriv('aes-256-cbc', key, iv)
var plaintext = decryptor.update(ciphertext, 'binary', 'utf8')
plaintext += decryptor.final('utf8')
console.log(plaintext)
// gmail.com
因此,只要您将 Swift 例程的输出作为 node.js 例程的输入(类似于我上面的示例),您就可以开始了!
您可以在要共享的 负载之前和之后使用标签。该标签将是您的 headers.
喜欢<tag>string</tag>
所以如果你加密你会得到前 12 个随机字节
因此您需要忽略 **<tag>...</tag>**