Шифрование Swift SHA256 возвращает другую зашифрованную строку для сравнения с Целью C - PullRequest
2 голосов
/ 24 мая 2019

Я перенесу некоторые коды из цели c в swift. Я хочу зашифровать строку ключом, используя алгоритм SHA 256 в Swift. Но по сравнению с реализацией Objective C swift-код возвращает другую зашифрованную строку. Оба кода выглядят одинаково, только синтаксис различен. Может ли кто-нибудь помочь мне получить такой же результат в быстром тем же, что и в Objective C? Ниже приведены примеры кода на обоих языках.

Цель C:

NSString* key = @"1234567890123456789012345678901234567890123456789012345678901234";
const char *cKey = [key cStringUsingEncoding:NSASCIIStringEncoding];
const char *cData = [@"message" cStringUsingEncoding:NSASCIIStringEncoding];
unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
NSData *hash = [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];
 NSString* encryptedString = hash.base64Encoding;

Swift:

let key = "1234567890123456789012345678901234567890123456789012345678901234"
let cKey = key.cString(using: .ascii)!
let cData = "message".cString(using: .ascii)!
var digest = [CUnsignedChar](repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH))
CCHmac(CCHmacAlgorithm(kCCHmacAlgSHA256), cKey, cKey.count, cData, cData.count, &digest)
let hash = Data(digest)
let encryptedString = hash.base64EncodedString()

1 Ответ

3 голосов
/ 24 мая 2019

Проблема в том, что cKey и cData включают завершающий нулевой символ строк и в версии Swift, которая считается в cKey.count и cData.count, тогда как в версии Objective-C strlen(cKey) и strlen(cData) делают не считают завершающий нулевой символ строк.

Ведение

 CCHmac(CCHmacAlgorithm(kCCHmacAlgSHA256), cKey, strlen(key), cData, strlen("message", &digest)

вместо этого исправит проблему в вашем примере, но небезопасно для не-ASCII символов.

Что я на самом деле хотел бы сделать, так это преобразовать строки в Data значения (которые не включают завершающий нулевой байт) с представлением UTF-8. Затем передайте базовые байтовые буферы методу шифрования:

let key = "1234567890123456789012345678901234567890123456789012345678901234"
let cKey = Data(key.utf8)
let cData = Data("message".utf8)
var digest = [CUnsignedChar](repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH))
cKey.withUnsafeBytes { keyPtr in
    cData.withUnsafeBytes { dataPtr in
    CCHmac(CCHmacAlgorithm(kCCHmacAlgSHA256), keyPtr.baseAddress, cKey.count, dataPtr.baseAddress, cData.count, &digest)
    }
}
let hash = Data(digest)
let encryptedString = hash.base64EncodedString()

Это дает тот же результат ZNjnsz2Uv5L0PvWIJjSh0BrOovuRXOSFWQ0s1Rd8VSM=, что и ваш код Objective-C.

...