8

ライセンス検証ソリューションを開発しようとしています。RSA_private_encryptライセンスは、OpenSSL の機能を使用してサーバー上で暗号化されます。

Mac OX XI で使用するRSA_public_decryptと、魅力的に機能します。Windows では、非常に小さなコードを使用する必要があるため、OpenSSL や他のライブラリとリンクできず、MS Crypto API を使用する必要があります。

私は何が悪いのかを理解しようと数日を費やしましたが、うまくいきませんでした。公開鍵を正常にインポートできますが、ここで成功は終わりです。私は、CAPI でバイト順を逆にする必要があることを認識しているので、これは問題ではないかもしれません。

ブロブにさまざまなパラメータをロードするなどCryptVerifyMessageSignatureWithKey、すべてを試しましたが、まだ運がありません。CryptDecodeObject

これはGetLastError() == CRYPT_E_ASN1_BADTAG、BLOBがASN1形式ではないことを意味すると思います...GoogleはRSA_private_encryptの出力形式について何も教えていません...したがって、ここで完全に失われます。

OpenSSL に基づく OS X コードは次のとおりです。

void cr_license_init(const char* lic) {
    __cr_license_ = lic;
    unsigned char lic_encoded[CR_LIC_LEN];

    BIO* b64 = BIO_new(BIO_f_base64());
    BIO* licIn = BIO_new_mem_buf((void*)lic, -1);
    licIn = BIO_push(b64, licIn);

    if(BIO_read(licIn, lic_encoded, CR_LIC_LEN) == CR_LIC_LEN) {

        const unsigned char* key_data = license_pub_der;
        RSA* r = d2i_RSA_PUBKEY(NULL, &key_data, sizeof(license_pub_der));

        if(r != NULL) {
            if(__cr_license_data_ != NULL) {
                free((void*)__cr_license_data_);
            }
            __cr_license_data_ = malloc(CR_LIC_LEN);
            if(RSA_public_decrypt(CR_LIC_LEN, lic_encoded,
    (unsigned char*)__cr_license_data_, r, RSA_PKCS1_PADDING) &lt= 0) {
                free((void*)__cr_license_data_);
                __cr_license_data_ = NULL;
            }
            RSA_free(r);
        }
    }
    BIO_free_all(licIn);
}

Windows のコードのこの部分はうまく機能するので、公開鍵は問題ではないと思います。

__cr_license_ = lic;
unsigned char lic_encoded[CR_LIC_LEN];

DWORD dwSize;
if(CryptStringToBinaryA(__cr_license_, 0/*autocalculate*/, CRYPT_STRING_BASE64, lic_encoded, &dwSize, NULL, NULL) && dwSize == CR_LIC_LEN) {
HCRYPTPROV hProv;
if(CryptAcquireContext(&hProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
    PCERT_PUBLIC_KEY_INFO pki = NULL;
    DWORD dwKeySize;
    if(CryptDecodeObjectEx(X509_ASN_ENCODING, X509_PUBLIC_KEY_INFO, license_pub_der, sizeof(license_pub_der), CRYPT_ENCODE_ALLOC_FLAG, NULL, &pki, &dwKeySize)) {
        HCRYPTKEY hKey = 0;
        if(CryptImportPublicKeyInfo( hProv, X509_ASN_ENCODING, pki, &hKey)) {

しかし、その後、私がメッセージでやろうとすることはすべてCRYPT_E_ASN1_BADTAG. 、、で試しCryptMsgOpenToDecodeましたCryptMsgUpdate-何も機能しません。CryptDecodeObjectCryptVerifyMessageSignatureWithKey

基本的に、owlsteadが述べたように、問題はpkcs1とpkcs7の非互換性にあると思います。MS CAPI を使用して pkcs1 形式のインポート/変換などを行った経験のある人はいますか?

どんな助けや手がかりでも大歓迎です!前もって感謝します!

4

3 に答える 3

4

上位レベルと下位レベルの署名形式が混在しています。OpenSSL は、署名データのみを含む PKCS#1 v1.5 署名をデフォルトで想定しています。Windows は PKCS#7 コンテナーを想定しているようです。これらには PKCS#1 v1.5 が含まれる場合がありますが、これらのデータとその他のデータは ASN.1 BER タグ/長さ形式を使用してラップされます。Microsoft API がこれをデコードしようとすると、未加工の署名がコンテナー形式であると見なされ、デコードは失敗します。

于 2013-01-25T23:28:58.900 に答える
1

これが非常に明白で、リストを省略したり、質問を誤解したりしない限り、質問で言及した機能ではなく、CryptDecryptを使用してライセンスを復号化する必要があると思います。PKCS#1 v1.5 パディングで OpenSSL を使用しているように見え、CryptoAPI はそれをサポートしていないように見えるため (テストされていませんが、仕様には PKCS#1 v2 OAEP のみがリストされています)、おそらく使用CRYPT_DECRYPT_RSA_NO_PADDING_CHECKして検証する必要があります。復号化後に PKCS#1 v1.5 パディングを手動で削除します。

于 2013-01-26T14:59:00.427 に答える