3DES 加密结果与示例不同
3DES Encryption result different from example
我有一个 3DES 加密示例,我必须遵循它才能在 NFC 卡上进行身份验证。这是示例:
因此 51E764602678DF2B 变为 577293FD2F34CA51,密钥 = 49454D4B41455242214E4143554F5946,IV = 0000000000000000
我成功地在这个网站上得到了正确的结果:
http://tripledes.online-domain-tools.com/
我试过 swift 和 https://github.com/sgl0v/SCrypto 如下:
func testScrypto() {
let plaintext = "51E764602678DF2B".data(using: String.Encoding.utf8)!
let sharedSecretKey = "49454D4B41455242214E4143".data(using: String.Encoding.utf8)!
let IV = "0000000000000000".data(using: String.Encoding.utf8)!
let ciphertext = try! plaintext.encrypt(.tripleDES, options: .PKCS7Padding, key: sharedSecretKey, iv: IV)
let plaintext2 = try! ciphertext.decrypt(.tripleDES, options: .PKCS7Padding, key: sharedSecretKey, iv: IV)
print("cipher = \(ciphertext.hexString())")
print("plaintext2 = \(plaintext2.hexString())")
}
public extension Data {
func bytesArray<T: ExpressibleByIntegerLiteral>() -> [T] {
var bytes = Array<T>(repeating: 0, count: self.count)
(self as NSData).getBytes(&bytes, length:self.count * MemoryLayout<T>.size)
return bytes
}
func hexString() -> String {
let hexString = NSMutableString()
let bytes: [UInt8] = self.bytesArray()
for byte in bytes {
hexString.appendFormat("%02x", UInt(byte))
}
return hexString as String
}
}
结果是:
cipher = d4c4a9637bcb4a435982330a42d1357b9e4539886a983535
plaintext2 = 35314537363436303236373844463242
35314537363436303236373844463242 是 51E764602678DF2B 如果我从十六进制字符串转换为纯文本但另一个字符串根本不是 577293FD2F34CA51
我也试过这个库https://www.example-code.com/swift/crypt2_3des.asp
但结果还是错误
我不知道是否有人知道如何在 swift 上执行此操作或者是加密方面的专家?
谢谢!
已提供的明文数据和密钥以十六进制编码。但是,您将它们编码为 UTF-8 文本,这不是一回事。
我成功解决了问题
问题是密钥只有 16 个字节,需要 24 个,所以我猜它是随机填充的,但预计它是第一个 8 个字节要放回到 16 个字节的末尾以便执行 24 个?
这样就可以了:
func fillKey(keyLength: size_t, key: Data) -> Data {
let missingBytes = keyLength - key.count
if missingBytes > 0 {
let keyBytes = (key as NSData).bytes
var bytes = [UInt8](repeating: UInt8(0), count: keyLength)
memccpy(&bytes[0], keyBytes.advanced(by: 0), Int32(key.count), key.count)
memccpy(&bytes[key.count], keyBytes.advanced(by: 0), Int32(missingBytes), missingBytes)
return Data(bytes: bytes)
} else {
return key
}
}
func my3DESEncrypt(encryptData: String, key: String, iv: String) -> Data? {
var myKeyData : Data = key.hexadecimal()!
let myIvData : Data = iv.hexadecimal()!
var myRawData : Data = encryptData.hexadecimal()!
let buffer_size : size_t = myRawData.count + kCCBlockSize3DES
var buffer = [UInt8](repeating: UInt8(0), count: buffer_size)
var num_bytes_encrypted : size_t = 0
let operation: CCOperation = UInt32(kCCEncrypt)
let algoritm: CCAlgorithm = UInt32(kCCAlgorithm3DES)
let options: CCOptions = 0
let keyLength = size_t(kCCKeySize3DES)
myKeyData = self.fillKey(keyLength: keyLength, key: myKeyData)
let Crypto_status: CCCryptorStatus = CCCrypt(operation, algoritm, options, (myKeyData as NSData).bytes, keyLength, (myIvData as NSData).bytes, (myRawData as NSData).bytes, myRawData.count, &buffer, buffer_size, &num_bytes_encrypted)
if UInt32(Crypto_status) == UInt32(kCCSuccess) {
let data = Data(bytes: buffer, count: num_bytes_encrypted)
return data
} else{
return nil
}
}
func my3DESDecrypt(decryptData : Data, key: String, iv: String) -> Data? {
let mydata_len : Int = decryptData.count
var myKeyData : Data = key.hexadecimal()!
let myIvData : Data = iv.hexadecimal()!
let buffer_size : size_t = mydata_len+kCCBlockSize3DES
var buffer = [UInt8](repeating: UInt8(0), count: buffer_size)
var num_bytes_encrypted : size_t = 0
let operation: CCOperation = UInt32(kCCDecrypt)
let algoritm: CCAlgorithm = UInt32(kCCAlgorithm3DES)
let options: CCOptions = UInt32(kCCOptionPKCS7Padding)
let keyLength = size_t(kCCKeySize3DES)
myKeyData = self.fillKey(keyLength: keyLength, key: myKeyData)
let decrypt_status : CCCryptorStatus = CCCrypt(operation, algoritm, options, (myKeyData as NSData).bytes, keyLength, (myIvData as NSData).bytes, (decryptData as NSData).bytes, mydata_len, &buffer, buffer_size, &num_bytes_encrypted)
if UInt32(decrypt_status) == UInt32(kCCSuccess){
let data = Data(bytes: buffer, count: num_bytes_encrypted)
return data
} else{
return nil
}
}
我有一个 3DES 加密示例,我必须遵循它才能在 NFC 卡上进行身份验证。这是示例:
因此 51E764602678DF2B 变为 577293FD2F34CA51,密钥 = 49454D4B41455242214E4143554F5946,IV = 0000000000000000 我成功地在这个网站上得到了正确的结果: http://tripledes.online-domain-tools.com/
我试过 swift 和 https://github.com/sgl0v/SCrypto 如下:
func testScrypto() {
let plaintext = "51E764602678DF2B".data(using: String.Encoding.utf8)!
let sharedSecretKey = "49454D4B41455242214E4143".data(using: String.Encoding.utf8)!
let IV = "0000000000000000".data(using: String.Encoding.utf8)!
let ciphertext = try! plaintext.encrypt(.tripleDES, options: .PKCS7Padding, key: sharedSecretKey, iv: IV)
let plaintext2 = try! ciphertext.decrypt(.tripleDES, options: .PKCS7Padding, key: sharedSecretKey, iv: IV)
print("cipher = \(ciphertext.hexString())")
print("plaintext2 = \(plaintext2.hexString())")
}
public extension Data {
func bytesArray<T: ExpressibleByIntegerLiteral>() -> [T] {
var bytes = Array<T>(repeating: 0, count: self.count)
(self as NSData).getBytes(&bytes, length:self.count * MemoryLayout<T>.size)
return bytes
}
func hexString() -> String {
let hexString = NSMutableString()
let bytes: [UInt8] = self.bytesArray()
for byte in bytes {
hexString.appendFormat("%02x", UInt(byte))
}
return hexString as String
}
}
结果是:
cipher = d4c4a9637bcb4a435982330a42d1357b9e4539886a983535
plaintext2 = 35314537363436303236373844463242
35314537363436303236373844463242 是 51E764602678DF2B 如果我从十六进制字符串转换为纯文本但另一个字符串根本不是 577293FD2F34CA51
我也试过这个库https://www.example-code.com/swift/crypt2_3des.asp 但结果还是错误
我不知道是否有人知道如何在 swift 上执行此操作或者是加密方面的专家?
谢谢!
已提供的明文数据和密钥以十六进制编码。但是,您将它们编码为 UTF-8 文本,这不是一回事。
我成功解决了问题 问题是密钥只有 16 个字节,需要 24 个,所以我猜它是随机填充的,但预计它是第一个 8 个字节要放回到 16 个字节的末尾以便执行 24 个?
这样就可以了:
func fillKey(keyLength: size_t, key: Data) -> Data {
let missingBytes = keyLength - key.count
if missingBytes > 0 {
let keyBytes = (key as NSData).bytes
var bytes = [UInt8](repeating: UInt8(0), count: keyLength)
memccpy(&bytes[0], keyBytes.advanced(by: 0), Int32(key.count), key.count)
memccpy(&bytes[key.count], keyBytes.advanced(by: 0), Int32(missingBytes), missingBytes)
return Data(bytes: bytes)
} else {
return key
}
}
func my3DESEncrypt(encryptData: String, key: String, iv: String) -> Data? {
var myKeyData : Data = key.hexadecimal()!
let myIvData : Data = iv.hexadecimal()!
var myRawData : Data = encryptData.hexadecimal()!
let buffer_size : size_t = myRawData.count + kCCBlockSize3DES
var buffer = [UInt8](repeating: UInt8(0), count: buffer_size)
var num_bytes_encrypted : size_t = 0
let operation: CCOperation = UInt32(kCCEncrypt)
let algoritm: CCAlgorithm = UInt32(kCCAlgorithm3DES)
let options: CCOptions = 0
let keyLength = size_t(kCCKeySize3DES)
myKeyData = self.fillKey(keyLength: keyLength, key: myKeyData)
let Crypto_status: CCCryptorStatus = CCCrypt(operation, algoritm, options, (myKeyData as NSData).bytes, keyLength, (myIvData as NSData).bytes, (myRawData as NSData).bytes, myRawData.count, &buffer, buffer_size, &num_bytes_encrypted)
if UInt32(Crypto_status) == UInt32(kCCSuccess) {
let data = Data(bytes: buffer, count: num_bytes_encrypted)
return data
} else{
return nil
}
}
func my3DESDecrypt(decryptData : Data, key: String, iv: String) -> Data? {
let mydata_len : Int = decryptData.count
var myKeyData : Data = key.hexadecimal()!
let myIvData : Data = iv.hexadecimal()!
let buffer_size : size_t = mydata_len+kCCBlockSize3DES
var buffer = [UInt8](repeating: UInt8(0), count: buffer_size)
var num_bytes_encrypted : size_t = 0
let operation: CCOperation = UInt32(kCCDecrypt)
let algoritm: CCAlgorithm = UInt32(kCCAlgorithm3DES)
let options: CCOptions = UInt32(kCCOptionPKCS7Padding)
let keyLength = size_t(kCCKeySize3DES)
myKeyData = self.fillKey(keyLength: keyLength, key: myKeyData)
let decrypt_status : CCCryptorStatus = CCCrypt(operation, algoritm, options, (myKeyData as NSData).bytes, keyLength, (myIvData as NSData).bytes, (decryptData as NSData).bytes, mydata_len, &buffer, buffer_size, &num_bytes_encrypted)
if UInt32(decrypt_status) == UInt32(kCCSuccess){
let data = Data(bytes: buffer, count: num_bytes_encrypted)
return data
} else{
return nil
}
}