c 库的openssl签名结果与openssl命令行的签名结果不一致

使用openssl命令行签名数据方式如下:

生成公私钥
Generate key pair:
openssl genrsa -out private.pem 1024

通过私钥导出公钥
Extract public key:
openssl rsa -in private.pem -out public.pem -outform PEM -pubout

生成签名
openssl dgst -sha256 -sign private.pem < data.txt > sign2

该签名结果为二进制,可以通过notepad++的查看十六进制插件进行查看。插件名称HEX-Editor, 非常好用的插件。

使用RSA_sign方法,得到的值与该结果不一致。
更换了如下方法后,可以正常签名、验签。请注意,我这边的私钥和公钥,不是通过读取文件获取的,是通过读取内存中的字符串获取,且格式是固定的,不能删除换行符和首行、尾行。如果想通过文件读取,网上的技术文章也比较多,公私钥格式如下:

-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCwhe6xy1m5dEbtjbCEJUjUMjC05zXctPxYynGl3jeko3jfAe/k
dSAuQ44EbZWRCdRJt61th2jouREdrQsQpiTkIxyrqKQISeAa4wFQwAyxosZ3fKI5
sag7wo/w6uBAdi7DVXMra7oTrN4Ostaf9PU7RsWcJ/jblyQDfSIj8vCOnwIBAwKB
gHWunyEyO9D4L0kJIFgY2zghdc3veT3N/ZCG9m6UJRhs+z9Wn+2jasmCXq2eY7YG
jYZ6c55aRfB7YL5zXLXEGJb7mmwhVetMiV69bKI3DXRPy8vySxgy2jc5lPLVZtmt
XYiwgnsY1MmqwFHTIJXPNvfLH3wkDfvfCtWdpmoxVL2bAkEA36g8ew0ODhk4FOcc
G55rCMaX4fQWlwOfLH7hrCDADQZYrVotOYdKMrFeXZ3y0yZ6QOJQ/CrIoFT/IriO
BVL2NQJBAMoMzPuWGUj41LH3QVHaGCJOLa89fs5dSb+xov6lOeUcHZ9VRYzzmvoM
NZiHzGr8TVU0EPW5GSg+w+3v9qOefAMCQQCVGtL8s160ENAN72gSaZywhGVBTWRk
rRTIVJZywIAIruXI5sjRBNwhy5Q+aUyMxFGAluCoHIXAOKoXJbQDjKQjAkEAhrMz
UmQQ21CNy/ori+a6wYlzyij/ND4xKnZsqcN77hK+ajjZCKJnUV15EFqIR1LeOM1g
o9C7cCnX8/VPF779VwJBAMegnSQ3sl/U86Iec2LxQ44NWhwWVTcBm2nyjtxmJTBD
0vh3KeuQHMDMsw3ziMCiRt5D4KExRGCYlfXVfyDlzxk=
-----END RSA PRIVATE KEY-----

-----BEGIN PUBLIC KEY-----
MIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQCwhe6xy1m5dEbtjbCEJUjUMjC0
5zXctPxYynGl3jeko3jfAe/kdSAuQ44EbZWRCdRJt61th2jouREdrQsQpiTkIxyr
qKQISeAa4wFQwAyxosZ3fKI5sag7wo/w6uBAdi7DVXMra7oTrN4Ostaf9PU7RsWc
J/jblyQDfSIj8vCOnwIBAw==
-----END PUBLIC KEY-----
int rsa_prikey_sign(const char *strprikey, unsigned char *data, int data_len, unsigned char *signtext, int *signtext_len)
{
    int ret = RSA_CRYPTO_OK;

    RSA *rsa = NULL; 
    BIO *keybio = NULL; 

    int len;

    EVP_PKEY *evpKey = NULL; 
    EVP_MD_CTX ctx;


    if(NULL == strprikey || NULL == data || NULL == signtext || NULL == signtext_len)
    {
        return RSA_PRAGMA_ERROR;
    }

    if('\0' == *strprikey || data_len <= 0)
    {
        return RSA_PRAGMA_ERROR;
    }

    do{
        rsa = RSA_new();
        keybio = BIO_new_mem_buf((unsigned char *)strprikey, -1); 

        rsa = PEM_read_bio_RSAPrivateKey(keybio, &rsa, NULL, NULL); 
        if(NULL == rsa)
        {
           ret = RSA_READ_PRIKEY_ERROR;
           break;
        }
  
        evpKey = EVP_PKEY_new();
        if (evpKey == NULL) {
            ret = RSA_MALLOC_ERROR;
            break;
        }

        if (EVP_PKEY_set1_RSA(evpKey, rsa) != 1) {
            ret =  RSA_READ_PRIKEY_ERROR;
            break;
        }

        EVP_MD_CTX_init(&ctx);

        if (EVP_SignInit_ex(&ctx, 
                        EVP_sha256(), NULL) != 1) {
            ret = RSA_SIGN_ERROR;
            break;
        }

        if (EVP_SignUpdate(&ctx, 
                        data, data_len) != 1) {
            ret = RSA_SIGN_ERROR;
            break;
        }   
    
        if (EVP_SignFinal(&ctx, 
                        (unsigned char*)signtext,
                        signtext_len, evpKey) != 1) {
            ret = RSA_SIGN_ERROR;
            break;
        }
        printf("RSA_sign len = %d\n", *signtext_len);
        printHex(signtext, *signtext_len);

        ret = RSA_CRYPTO_OK;
        EVP_MD_CTX_cleanup(&ctx);

    }while(0);
    
    
    if (rsa != NULL) {
        RSA_free(rsa);
        rsa = NULL;
    }

    if (evpKey != NULL) {
        EVP_PKEY_free(evpKey);
        evpKey = NULL;
    }

    if (keybio != NULL) {
        BIO_free_all(keybio);
        keybio = NULL;
    }

    return ret;
}

int rsa_pubkey_verify(const char *strpubkey, unsigned char *data, int data_len,
        unsigned char *signtext, int signtext_len)
{
    int ret = RSA_CRYPTO_OK;

    RSA *rsa = NULL; 
    BIO *keybio = NULL; 
    EVP_PKEY *evpKey = NULL; 
    EVP_MD_CTX ctx;
    int len;

    if(NULL == strpubkey || NULL == signtext || NULL == data)
    {
        return RSA_PRAGMA_ERROR;
    }

    if('\0' == *strpubkey || signtext_len <= 0 || data_len <= 0 )
    {
        return RSA_PRAGMA_ERROR;
    }

  

    do{

        rsa = RSA_new();
        keybio = BIO_new_mem_buf((unsigned char *)strpubkey, -1); 

        rsa = PEM_read_bio_RSA_PUBKEY(keybio, &rsa, NULL, NULL);
        if(NULL == rsa)
        {
            ret = RSA_READ_PUBKEY_ERROR;
            break;
        }
  
        evpKey = EVP_PKEY_new();
        if (evpKey == NULL) {
            ret = RSA_MALLOC_ERROR;
            break;
        }

        if (EVP_PKEY_set1_RSA(evpKey, rsa) != 1) {
            ret =  RSA_READ_PRIKEY_ERROR;
            break;
        }

        EVP_MD_CTX_init(&ctx);

        if (EVP_SignInit_ex(&ctx, 
                        EVP_sha256(), NULL) != 1) {
            ret = RSA_SIGN_ERROR;
            break;
        }

        if (EVP_VerifyUpdate(&ctx, 
                        data, data_len) != 1) {
            ret = RSA_SIGN_ERROR;
            break;
        }   
    
        if (EVP_VerifyFinal(&ctx, 
                        (unsigned char*)signtext,
                        signtext_len, evpKey) != 1) {
            ret = RSA_VERIFY_ERROR;
            break;
        }

        ret = RSA_CRYPTO_OK;
        EVP_MD_CTX_cleanup(&ctx);

    }while(0);
    
    
    if (rsa != NULL) {
        RSA_free(rsa);
        rsa = NULL;
    }

    if (evpKey != NULL) {
        EVP_PKEY_free(evpKey);
        evpKey = NULL;
    }

    if (keybio != NULL) {
        BIO_free_all(keybio);
        keybio = NULL;
    }

    return ret;
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容