Chilkat iOS10+ RSA проблема совместимости
Я использую нативный RSA в одном приложении для iOS и библиотеку Chilkat RSA в другом. На нативной стороне iOS я шифрую (OAEP SHA256) данные с помощью следующей функции:
static func encryptWithKey(_ data: Data, rsaKey: SecKey) -> Data? {
let algorithm = SecKeyAlgorithm.rsaEncryptionOAEPSHA256
guard SecKeyIsAlgorithmSupported(rsaKey, .encrypt, algorithm) else { return nil }
var error: Unmanaged<CFError>?
let encryptedData = SecKeyCreateEncryptedData(rsaKey, algorithm, data as CFData, &error)
if let encryptionError = error {
print(encryptionError.takeRetainedValue())
}
return encryptedData as Data?
}
а затем в другом приложении я расшифровываю эти данные с помощью библиотеки Chilkat:
static func decrypt(base64 encryptedText: String, with xmlKey: String) -> Data? {
let privateKey = CkoPrivateKey()
guard let success = privateKey?.loadXml(xmlKey), success else { return nil }
guard let rsa = CkoRsa() else { return nil }
rsa.unlockComponent(Chilkat.key)
rsa.oaepPadding = true
rsa.littleEndian = false
rsa.oaepHash = "sha256"
rsa.encodingMode = "base64"
rsa.importPrivateKeyObj(privateKey)
if let decryptedData = rsa.decryptBytesENC(encryptedText, bUsePrivateKey: true) {
return decryptedData
} else {
print(rsa.lastErrorText)
}
return nil
}
Даже когда я использовал одну пару закрытых / открытых ключей, я получаю сообщение об ошибке (от rsa.lastErrorText):
"ChilkatLog:
DecryptBytesENC(7ms):
DllDate: Feb 1 2018
ChilkatVersion: 9.5.0.72
UnlockPrefix: XXXXXXXXXXXX
Architecture: Little Endian; 64-bit
Language: IOS C/C++/Swift/Objective-C
VerboseLogging: 1
usePrivateKey: 1
Component successfully unlocked using purchased unlock code.
rsaDecryptBytes(7ms):
rsa_decrypt(7ms):
KeyType: Private
InputSize: 256
Padding: OAEP
OaepHashAlg: SHA-256
MgfHashAlg: SHA-1
ParamLen: 0
ModulusBitLen: 2048
inlen: 256
modulus_bytelen: 256
modulus_bitlen: 2048
bigEndian: 0
Byte swapping from big-endian to little-endian
padding: OAEP
No leading zero byte for OAEP decoding.
OAEP decoding failed.
--rsa_decrypt
--rsaDecryptBytes
Failed.
--DecryptBytesENC
--ChilkatLog"
Есть идеи?
2 ответа
Я добавил некоторые дополнительные записи, чтобы мы могли видеть байты (в шестнадцатеричном формате) после расшифровки RSA, но до распаковки OAEP. После расшифровки RSA (но до распаковки OAEP) мы должны увидеть байты в этом формате:
0x00 || maskedseed || maskedDB
Другими словами, первый байт результата ДОЛЖЕН быть 0 байтом. Если закрытый ключ RSA, используемый для расшифровки, не соответствует открытому ключу, используемому для шифрования, то мы увидим случайные байты. (т.е. 1-й байт не будет 0). Masedseed и maskedDB по-прежнему будут отображаться как случайные байты.
Проблема была в хэш-функции OAEP Mgf. Если вы установите oaepMgfHash = "sha256", он станет совместимым с собственной реализацией iOS RSA. Кроме того, библиотека Chilkat обеспечивает автоматический откат к правильной функции oaepMgfHash в случае, если вы указали ее неправильно. Спасибо, Мэтт!