2011-11-26 31 views
7

公開鍵でbase64文字列を読み取り、文字列を暗号化するルーチンをC言語で作成しています。私はまた、同じ文字列の復号化をテストするが、デコードをやろうとしたとき、私は、エラー0x0407106Bを取得しています:私はOpenSSLを使用した暗号化と復号化エラー0x0407106B

openssl rsa -in rsa_privatekey.pem -check 
を使用して秘密鍵をエクスポート:

$ openssl errstr 0x0407106B 
error:0407106B:rsa routines:RSA_padding_check_PKCS1_type_2:block type is not 02 

ここでコード

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <ctype.h> 
#include <openssl/rsa.h> 
#include <openssl/engine.h> 

//#define PADDING RSA_PKCS1_OAEP_PADDING 
#define PADDING RSA_PKCS1_PADDING 
//#define PADDING RSA_NO_PADDING 

main() { 

// public key 
char *b64_pKey = "-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCp2w+8HUdECo8V5yuKYrWJmUbL\ntD6nSyVifN543axXvNSFzQfWNOGVkMsCo6W4hpl5eHv1p9Hqdcf/ZYQDWCK726u6\nhsZA81AblAOOXKaUaxvFC+ZKRJf+MtUGnv0v7CrGoblm1mMC/OQI1JfSsYi68Epn\naOLepTZw+GLTnusQgwIDAQAB\n-----END PUBLIC KEY-----\n"; 

// private key 
char *b64priv_key = "-----BEGIN RSA PRIVATE KEY-----\nMIICXAIBAAKBgQCp2w+8HUdECo8V5yuKYrWJmUbLtD6nSyVifN543axXvNSFzQfW\nNOGVkMsCo6W4hpl5eHv1p9Hqdcf/ZYQDWCK726u6hsZA81AblAOOXKaUaxvFC+ZK\nRJf+MtUGnv0v7CrGoblm1mMC/OQI1JfSsYi68EpnaOLepTZw+GLTnusQgwIDAQAB\nAoGBAKDuq3PikblH/9YS11AgwjwC++7ZcltzeZJdGTSPY1El2n6Dip9ML0hUjeSM\nROIWtac/nsNcJCnvOnUjK/c3NIAaGJcfRPiH/S0Ga6ROiDfFj2UXAmk/v4wRRUzr\n5lsA0jgEt5qcq2Xr/JPQVGB4wUgL/yQK0dDhW0EdrJ707e3BAkEA1aIHbmcVfCP8\nY/uWuK0lvWxrIWfR5MlHhI8tD9lvkot2kyXiV+jB6/gktwk1QaFsy7dCXn7w03+k\nxrjEGGN+kQJBAMuKf55lDtU9K2Js3YSStTZAXP+Hz7XpoLxmbWFyGvBx806WjgAD\n624irwS+0tBxkERbRcisfb2cXmAx8earT9MCQDZuVCpjBWxd1t66qYpgQ29iAmG+\njBIY3qn9uOOC6RSTiCCx1FvFqDMxRFmGdRVFxeyZwsVE3qNksF0Zko0MPKECQCEe\noDV97DP2iCCz5je0R5hUUM2jo8DOC0GcyR+aGZgWcqjPBrwp5x08t43mHxeb4wW8\ndFZ6+trnntO4TMxkA9ECQB+yCPgO1zisJWYuD46KISoesYhwHe5C1BQElQgi9bio\nU39fFo88w1pok23a2CZBEXguSvCvexeB68OggdDXvy0=\n-----END RSA PRIVATE KEY-----\n"; 

// String to encrypt 
char *str = "1234"; 

ERR_load_crypto_strings(); 

BIO *bpo = BIO_new_mem_buf(b64_pKey, -1); 
RSA *pubKey = PEM_read_bio_RSA_PUBKEY(bpo, NULL, NULL, NULL); 

if (!pubKey) { 
    printf("%s\n", ERR_error_string(ERR_get_error(), NULL)); 
    return; 
} 

int rsa_length = RSA_size(pubKey); 

BIO *b64 = NULL; 
BIO *bmem = NULL; 
BUF_MEM *bptr = NULL; 

unsigned char encrypted[2560] = { 0 }; 
unsigned char retencrypted[2560] = { 0 }; 

int resultEncrypt = RSA_public_encrypt(PADDING, str, encrypted, pubKey, PADDING); 
if (resultEncrypt == -1) { 
    printf("%s\n", ERR_error_string(ERR_get_error(), NULL)); 
    return; 
} 

/* 
* Show base 64 encrypted string 
*/ 
b64 = BIO_new((BIO_METHOD *)BIO_f_base64()); 
BIO_set_flags(b64,BIO_FLAGS_BASE64_NO_NL); 
bmem = BIO_new(BIO_s_mem()); 
b64 = BIO_push(b64, bmem); 
BIO_write(b64, encrypted, resultEncrypt); 
BIO_flush(b64); 
BIO_get_mem_ptr(b64, &bptr); 

memcpy(retencrypted, bptr->data, bptr->length); 
BIO_free(b64); 
BIO_free(bpo); 
RSA_free(pubKey); 

printf("Encrypted string:%s\n",retencrypted); 

/* 
* Now decrypt this very string with the private key 
*/ 

BIO *bpop = BIO_new_mem_buf(b64priv_key, -1); 
RSA *privKey = PEM_read_bio_RSAPrivateKey(bpop, NULL, NULL, NULL); 

if (!privKey) { 
    printf("%s\n", ERR_error_string(ERR_get_error(), NULL)); 
    return; 
} 

rsa_length = RSA_size(privKey); 

unsigned char decrypted[2560] = { 0 }; 

int resultDecrypt = RSA_private_decrypt(RSA_size(privKey), retencrypted, decrypted, privKey, PADDING); 

if (resultDecrypt == -1) { 
    printf("%s\n", ERR_error_string(ERR_get_error(), NULL)); 
    return; 
} 

printf("resultDecrypt=%d\ndecrypted string: %s\n",resultDecrypt,decrypted); 
BIO_free(bpop); 
RSA_free(privKey); 
ERR_free_strings(); 
} 

注意です

と公開鍵:

openssl rsa -in rsa_privatekey.pem -pubout 

エラーが発生するのはなぜですか?

+0

証明書文字列の最後に改行が必要ですか? http://srdevspot.blogspot.com/2011/08/openssl-error0906d064pem.html – mdec

+0

両方のキーに改行を追加しようとしましたが、同じ結果がありました。 – xain

+1

私は[あなたの例をここで修正しました](https://gist.github.com/superwills/5415344) – bobobobo

答えて

3

問題は、base64でエンコードされた結果を復号化しようとしていることです。 暗号化の結果を解読しようとする必要があります。

int resultEncrypt = RSA_public_encrypt(PADDING, str, encrypted, pubKey, PADDING); 

は、なぜあなたは渡している。また、暗号化コールに問題がある

int resultDecrypt = RSA_private_decrypt(RSA_size(privKey), encrypted, decrypted, privKey, PADDING); 

int resultDecrypt = RSA_private_decrypt(RSA_size(privKey), retencrypted, decrypted, privKey, PADDING); 

あなたが呼び出す必要があります:、代わりにされ

flenとしてパッドしていますか?これは文字列の長さ(ヌル文字を暗号化するかどうかに応じて4または5)になります。

暗号化された文字列をASCII形式(base64を使用してエンコード)で書きたい場合は問題ありません。しかし、解読する前に解読する必要があります。

1

エラーはblock type is not 02です。

Omriが間違ったデータを渡していて、1バイトのみを暗号化しようとしていますが、sizeof(encrypted)が大きすぎる(2560)ためエラーです。換言すれば、RSA_public_encryptのデータ受信者は、unsigned char*ポインタunsigned char[2560]でなければなりません。あなたは

unsigned char encrypted[2560] = { 0 }; //X 2560?? RSA_public_encrypt fails. 

を持って

それはDATALENデータでなければなりませんしながら、あなたは、あなたがRSA_public_encryptに最初の引数としてPADDINGを使用したことを、

unsigned char *encrypted = (unsigned char*)malloc(rsa_length) ; 
RSA_public_encrypt(DATALEN, (const unsigned char*)str, encrypted, pubKey, PADDING) ; 

お知らせオムリが指摘したエラーを使用する必要があります長さ

これを修正すると、後で秘密鍵の復号化で同様のエラーが発生します。それを修正して、あなたの方法にしている。