Dekripsi kunci publik RSA di OS X menggunakan SecTransform API (atau API sistem lainnya)

Saya mencoba mengganti penggunaan OpenSSL saya, yang sudah lama tidak digunakan lagi dan telah dihapus dari SDK 10.11 dengan Security Transform API. Penggunaan OpenSSL saya hanya untuk verifikasi kunci lisensi. Masalah yang saya hadapi adalah kunci lisensi dibuat (sisi server) menggunakan fungsi rsa_private_encrypt() OpenSSL, bukan (mungkin lebih tepat) rsa_sign(). Dalam kode OpenSSL saat ini, saya memverifikasinya menggunakan rsa_public_decrypt() seperti:

int decryptedSize = RSA_public_decrypt([signature length], [signature bytes], checkDigest, rsaKey, RSA_PKCS1_PADDING);
BOOL success = [[NSData dataWithBytes:checkDigest length:decryptedSize] isEqualToData:[digest sha1Hash]]) 

Sayangnya, saya tidak dapat mereplikasi ini menggunakan API SecTransform. Saya punya yang berikut ini:

SecTransformRef decryptor = CFAutorelease(SecDecryptTransformCreate(pubKey, &error));
if (error) { showSecError(error); return NO; }
SecTransformSetAttribute(decryptor, kSecTransformInputAttributeName, (CFDataRef)signatureData, &error);
if (error) { showSecError(error); return NO; }

CFDataRef result = SecTransformExecute(decryptor, &error);
if (error) { showSecError(error); return NO; }
return CFEqual(result, (CFDataRef)[digest sha1Hash]);

Panggilan ke SecTransformExecute() gagal dengan kesalahan CSSMERR_CSP_INVALID_KEY_CLASS.

Apakah saya melewatkan sesuatu, atau tidak ada yang setara dengan RSA_public_decrypt() OpenSSL di Security.framework? Mungkin SecVerifyTransform dapat digunakan (Saya juga tidak dapat menjalankannya, tetapi hal yang sama juga berlaku untuk RSA_sign() OpenSSL). Saya tentu saja bersedia menggunakan API sistem lain (misalnya CDSA/CSSM) jika itu memungkinkan saya melakukan ini.

Sayangnya, karena kode ini perlu memverifikasi kode lisensi yang ada, saya tidak bisa begitu saja mengubah kode pembuatan lisensi untuk menggunakan RSA_sign() atau yang serupa.


person Andrew Madsen    schedule 11.10.2015    source sumber


Jawaban (1)


Saya menemukan cara melakukan ini menggunakan CDSA/CSSM. Kode di bawah ini:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"

NSData *ORSDecryptDataWithPublicKey(NSData *dataToDecrypt, SecKeyRef publicKey)
{
    const CSSM_KEY *cssmPubKey = NULL;
    SecKeyGetCSSMKey(publicKey, &cssmPubKey);
    CSSM_CSP_HANDLE handle;
    SecKeyGetCSPHandle(publicKey, &handle);

    CSSM_DATA inputData = {
        .Data = (uint8_t *)[dataToDecrypt bytes],
        .Length = [dataToDecrypt length],
    };

    CSSM_DATA outputData = {
        .Data = NULL,
        .Length = 0,
    };

    CSSM_ACCESS_CREDENTIALS credentials;
    memset(&credentials, 0, sizeof(CSSM_ACCESS_CREDENTIALS));
    CSSM_CC_HANDLE contextHandle;
    CSSM_RETURN result = CSSM_CSP_CreateAsymmetricContext(handle, cssmPubKey->KeyHeader.AlgorithmId, &credentials, cssmPubKey, CSSM_PADDING_PKCS1, &contextHandle);
    if (result) { NSLog(@"Error creating CSSM context: %i", result); return nil; }

    CSSM_CONTEXT_ATTRIBUTE modeAttribute = {
        .AttributeType = CSSM_ATTRIBUTE_MODE,
        .AttributeLength = sizeof(UInt32),
        .Attribute.Uint32 = CSSM_ALGMODE_PUBLIC_KEY,
    };
    result = CSSM_UpdateContextAttributes(contextHandle, 1, &modeAttribute);
    if (result) { NSLog(@"Error setting CSSM context mode: %i", result); return nil; }

    CSSM_SIZE numBytesDecrypted = 0;
    CSSM_DATA remData = {
        .Data = NULL,
        .Length = 0,
    };
    result = CSSM_DecryptData(contextHandle, &inputData, 1, &outputData, 1, &numBytesDecrypted, &remData);
    if (result) { NSLog(@"Error decrypting data using CSSM: %i", result); return nil; }
    CSSM_DeleteContext(contextHandle);

    outputData.Length = numBytesDecrypted;

    return [NSData dataWithBytesNoCopy:outputData.Data length:outputData.Length freeWhenDone:YES];
}

#pragma clang diagnostic pop

Perhatikan bahwa seperti yang didokumentasikan di sini, sementara CDSA tidak digunakan lagi, Apple merekomendasikan penggunaannya "jika tidak ada API layanan kriptografi lain yang mendukung apa yang Anda coba lakukan". Saya telah mengajukan radar #23063471 meminta fungsi ini ditambahkan ke Security.framework.

person Andrew Madsen    schedule 12.10.2015