Результат шифрования 3DES отличается от примера - PullRequest
0 голосов
/ 11 июня 2018

У меня есть пример шифрования 3DES, которому я должен следовать для аутентификации на картах NFC.Вот пример: enter image description here

Итак, 51E764602678DF2B становится 577293FD2F34CA51 с ключом = 49454D4B41455242214E4143554F5946 и IV = 0000000000000000 Мне удалось получить правильный результат на этом сайте: * 1006domain-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

Я также пробовал эту lib https://www.example -code.com / swift / crypt2_23des.* но результат все еще неправильный

Я не знаю, есть ли у кого-нибудь идея, как это сделать на swift или специалист по шифрованию?

спасибо!

Ответы [ 2 ]

0 голосов
/ 12 июня 2018

Мне удалось устранить проблему. Проблема заключалась в том, что ключ был только 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

    }
}
0 голосов
/ 11 июня 2018

Данные открытого ключа и ключ, которые были предоставлены, закодированы в шестнадцатеричном формате.Однако вы кодируете их как текст UTF-8, что не одно и то же.

...