【问题标题】:Encryption and decryption error 0x0407106B using OpenSSL使用OpenSSL加解密错误0x0407106B
【发布时间】:2012-01-06 17:12:07
【问题描述】:

我正在用 C 语言编写一个例程,它使用公钥读取 base64 字符串并继续加密字符串。我还测试了相同字符串的解密,但在尝试解码时出现错误 0x0407106B:

$ 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 -check

和公钥:

openssl rsa -in rsa_privatekey.pem -pubout

为什么我会收到错误消息?

【问题讨论】:

标签: c openssl rsa public-key-encryption


【解决方案1】:

问题是您正在尝试解密 base64 编码的结果。 您应该尝试解密加密的结果。

也就是说,而不是:

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

你应该打电话:

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

另外,加密调用有问题:

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

您为什么将 PADDING 传递为 flen?这应该是字符串的长度(即 4 或 5,取决于您是否要加密空字符)。

如果您想将加密字符串写为 ASCII(使用 base64 编码),那很好。但是你必须在解密之前把它解码回来。

【讨论】:

    【解决方案2】:

    你得到的错误是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.
    

    你应该使用

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

    注意 Omri 指出的错误,您使用 PADDING 作为 RSA_public_encrypt 的第一个参数,而它应该是 DATALEN 数据长度。

    如果您解决了这个问题,您稍后会在使用私钥解密时遇到类似的错误。修好它,你就可以上路了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-02-17
      • 2017-10-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多