كيفية تشفير البيانات كتلة صغيرة مع المفتاح العمومي RSA الوحيد باستخدام Microsoft ECSP؟

StackOverflow https://stackoverflow.com/questions/295345

  •  08-07-2019
  •  | 
  •  

سؤال

وأحتاج لتشفير كتلة صغيرة من البيانات (16 بايت) باستخدام 512 بت RSA المفتاح العمومي - تماما مهمة سهلة بالنسبة لمعظم المكتبات التشفير المعروفة بالنسبة لي، ما عدا MS CSP API، كما يبدو. وثائق عن CryptEncrypt وظيفة على أنه

<اقتباس فقرة>   

وموفر التشفير Microsoft المحسن يدعم التشفير RSA مباشر مع المفاتيح العامة والتشفير RSA مع مفاتيح خاصة. يستخدم التشفير PKCS # 1 الحشو.

وأنها لم تعمل لي على الرغم من. حسنا، يعمل قانون بلدي وتنتج تشفير كتلة من البيانات مع حجم الصحيح ولكن فشل بينسل إلى decypher ذلك. يبدو مثل الكثير من CryptEncrypt لا يزال يستخدم سايفر متماثل.

ومما يؤسف له جميع الأمثلة التي وجدتها تشير إلى التشفير جنبا إلى جنب مع سايفر متماثل، ولذا فإنني لم يكن لديك مثال عملي على أيدي التي من شأنها أن تجعل بالتأكيد الأمور أسهل.

ويمكن إرضاء أي شخص لي نقطة في هذا المثال أو اسمحوا لي أن أعرف إذا كان هناك بعض العثرات يست واضحة لقد غاب؟

وشكرا لكم.

هل كانت مفيدة؟

المحلول

وهذا يبدو وكأنه endianness القضية. CryptEncrypt وظيفة إرجاع النص المشفر في تنسيق endian طفيف، في حين يتوقع بينسل البيانات الخاصة به ليكون في شكل كبير-endian. ستحتاج إلى عكس البيانات المشفرة قبل تمريرها إلى بينسل.

نصائح أخرى

وهنا هو رمز (فقط في حال كان شخص ما قد غوغلد هذا الموضوع خارج):

BYTE *spkiData = SPKI; // X.509 ASN.1 encoded SubjectPublicKeyInfo
DWORD dwSPKISize = SPKI_SIZE; // 94 bytes for RSA

DWORD dwBufSize = 0;
// Get buffer size for decoded spki structure
CryptDecodeObject(X509_ASN_ENCODING, X509_PUBLIC_KEY_INFO, spkiData, dwSPKISize, 0, NULL, &dwBufSize);
BYTE* decBuf = new BYTE[dwBufSize];
CryptDecodeObject( X509_ASN_ENCODING, X509_PUBLIC_KEY_INFO, spkiData, dwSPKISize, 0, decBuf, &dwBufSize);
// Now decode the RSA Public key itself
CERT_PUBLIC_KEY_INFO * spki = (CERT_PUBLIC_KEY_INFO *) decBuf;
// Get buffer size for decoded public key structure
CryptDecodeObject( X509_ASN_ENCODING, RSA_CSP_PUBLICKEYBLOB, spki->PublicKey.pbData, spki->PublicKey.cbData, 0, 0, &dwBufSize);
// Get the RSA public key blob
BYTE *blobBuf = new BYTE[dwBufSize];
CryptDecodeObject(X509_ASN_ENCODING, RSA_CSP_PUBLICKEYBLOB, spki->PublicKey.pbData, spki->PublicKey.cbData, 0, blobBuf, &dwBufSize);
// Acquire crypto provider context
HCRYPTPROV hCryptProv = NULL;
CryptAcquireContext(&hCryptProv, 0, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
// Import key
HCRYPTKEY key = NULL;
CryptImportKey(hCryptProv, blobBuf, dwBufSize, 0, 0, &key);
// Get the key size
DWORD dwKeySize;
DWORD dwParamSize = sizeof(DWORD);
CryptGetKeyParam(key, KP_KEYLEN, (BYTE*) &dwKeySize, &dwParamSize, 0);
// we need it in bytes for convenience
dwKeySize /= 8;
// Now the fun
// allocate a buffer of key size
BYTE *data = new BYTE[dwKeySize];
// Copy data need to be encrypted
// With PKCS#1 padding data length can not exceed keysize - 11 bytes
DWORD dataLen = 16;
memcpy(data, "0123456789012345", dataLen);
CryptEncrypt(key, 0, TRUE, 0, data, &dataLen, dwKeySize)
// now convert it to big endian (for the rest of the world)
for (int i = 0; i < (dwKeySize / 2); i++) {
    BYTE c = data[i];
    data[i] = data[dwKeySize - 1 - i];
    data[dwKeySize - 1 - i] = c;
}
// now data points to a dwKeySize length block of RSA PKCS#v1.5 encrypted data
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top