Расшифровка DES с помощью CommonCrypto в Swift 3

Я хочу расшифровать строку, зашифрованную DES, с помощью CommonCrypto.

Я уже импортировал CommonCrypto с Bridging Header в свой проект.

При попытке и ошибке мне удалось вызвать функцию 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) ?? "???"
}

Этот код теперь возвращает правильный результат. Осталась только одна маленькая проблема: возвращенный результат String теперь выглядит следующим образом: "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) на мой результат String, прежде чем вернуть его.

1 ответ

Решение

Когда вы шифруете или дешифруете от 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 кода ниже.)


Еще один, когда вы хотите получить данные в изменяемый (var) Data, задавать count (не только capacity) из Data, (№ 2 и № 3)


ОБНОВЛЕНО И, как сказал zaph, вам нужно указать IV для режима CBC (по умолчанию) или использовать режим 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 "???"
Другие вопросы по тегам