29447945 发表于 2020-8-14 19:40

【树莓派4B测评】+openssl库代码测试

<div class='showpostmsg'><p align="center" style="text-align:center"><span style="font-size:10.5pt"><span style="font-family:等线">【树莓派4B测评】+openssl库代码测试</span></span></p>

<p align="left" style="text-align:left"><span style="font-size:10.5pt"><span style="font-family:等线">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 上一贴大体测试了使用openssl命令行对文本进行摘要算法,对称加解密,非对称算法加解密和签名验签的操作,接下来我们使用代码再完成一遍。</span></span></p>

<p align="left" style="text-align:left"><span style="font-size:10.5pt"><span style="font-family:等线">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; 首先是MD5摘要算法测试:</span></span></p>

<p align="left" style="text-align:left"><span style="font-size:10.5pt"><span style="font-family:等线">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span></p>

<pre>
<code class="language-cpp">unsigned char encrypt_file_path[]="test_data.txt";

unsigned char md5_file_path[]="md5_file.bin";
//MD5摘要算法测试
int MD5_test(void)
{
       
        MD5_CTX ctx;
        unsigned char outmd;
        char buffer;
        int len=0;
        int i;
        FILE * fp=NULL;
        memset(outmd,0,sizeof(outmd));
        memset(buffer,0,sizeof(buffer));

        //printf("MD5 test file name:%s\r\n",encrypt_file_path);
       
        fp=fopen(encrypt_file_path,"rb");
        if(fp==NULL)
        {
                printf("Can't open file\n");
                return 0;
        }

        MD5_Init(&amp;ctx);
        while((len=fread(buffer,1,1024,fp))&gt;0)
        {
                MD5_Update(&amp;ctx,buffer,len);
                memset(buffer,0,sizeof(buffer));
        }
        fclose(fp);
        MD5_Final(outmd,&amp;ctx);

        printf("file(%s) MD5 = ",encrypt_file_path);
        for(i=0;i&lt;16;i&lt;i++)
        {
                printf("%02X",outmd);
        }
        fp=fopen(md5_file_path,"wt");
        if(fp==NULL)
        {
                printf("Can't open file\n");
                return 0;
        }
        fwrite(outmd, 16 , 1, fp );
        fclose(fp);
        printf("\n");
        return 0;
}
</code></pre>

<p>还是测试上一次的文本文件,内容是0123456789;</p>

<p>首先编译:&nbsp;gcc -o test openssl_test.c -lssl -lcrypto</p>

<p>然后运行:./test</p>

<p>MD5值和上一贴中的值也能对应;</p>

<p>接着我们测试AES加解密:</p>

<pre>
<code class="language-cpp">
// out的内存大小需要注意 后边有 out += AES_BLOCK_SIZE
// 所以out 内存最小不能小于 AES_BLOCK_SIZE
int aes_encrypt(char* in, char* key, char* out)
{
    if (!in || !key || !out)
    {
      return 0;
    }

    AES_KEY aes;
    if (AES_set_encrypt_key((unsigned char*)key, 128, &amp;aes) &lt; 0)
    {
      return 0;
    }

    int len = strlen(in), en_len = 0;

    //输入输出字符串够长。而且是AES_BLOCK_SIZE的整数倍,须要严格限制
    while (en_len &lt; len)
    {
      AES_encrypt((unsigned char*)in, (unsigned char*)out, &amp;aes);
      in        += AES_BLOCK_SIZE;
      out += AES_BLOCK_SIZE;
      en_len += AES_BLOCK_SIZE;
    }

    return 1;
}

int aes_decrypt(char* in, char* key, char* out)
{
    if (!in || !key || !out)
    {
      return 0;
    }

    AES_KEY aes;
    if (AES_set_decrypt_key((unsigned char*)key, 128, &amp;aes) &lt; 0)
    {
      return 0;
    }

    int len = strlen(in), en_len = 0;
    while (en_len &lt; len)
    {
      AES_decrypt((unsigned char*)in, (unsigned char*)out, &amp;aes);
      in        += AES_BLOCK_SIZE;
      out += AES_BLOCK_SIZE;
      en_len += AES_BLOCK_SIZE;
    }

    return 1;
}

//AES加解密测试
int AES_test(void)
{
        AES_KEY aes;
       
        char outbuffer;
        char decrypt_buffer;
        char buffer;
        int en_len,len=0;
        int i;
        FILE * fp=NULL;
        unsigned char key[] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
        memset(outbuffer,0,sizeof(outbuffer));
        memset(buffer,0,sizeof(buffer));
        memset(decrypt_buffer,0,sizeof(decrypt_buffer));
       
        char *in = NULL;
        char *out = NULL;
       

       

        fp=fopen(encrypt_file_path,"rb");
        if(fp==NULL)
        {
                printf("Can't open file\n");
                return 0;
        }

        while((len=fread(buffer,1,1024,fp))&gt;0)
        {
                aes_encrypt(buffer, key, outbuffer);

                memset(buffer,0,sizeof(buffer));
        }
        fclose(fp);
        printf("AES encrypt:%s\r\n",outbuffer);

        aes_decrypt(outbuffer, key, decrypt_buffer);

       

        printf("AES decrypt = %s\r\n",decrypt_buffer);

        return 0;
}
</code></pre>

<p>还是编译运行结果如下图:</p>

<p>解密后得到原文;</p>

<p>然后是RSA加解密测试:</p>

<pre>
<code class="language-cpp">
#define PUBLICKEY "rsa_public_key.pem"
#define PRIVATEKEY "rsa_private_key.pem"

#define PASS "8888" //口令

//RSA加密测试
int RSA_test(void)
{
        char outbuffer;
        int filelen=0;
        FILE *fp = NULL;
        RSA *publicRsa = NULL;
        RSA *privateRsa = NULL;
        if ((fp = fopen(PUBLICKEY, "r")) == NULL)
        {
                printf("public key path error\n");
                return -1;
        }        
   
        if ((publicRsa = PEM_read_RSA_PUBKEY(fp, NULL, NULL, NULL)) == NULL)
        {
                printf("PEM_read_RSA_PUBKEY error\n");
                return -1;
        }
        fclose(fp);
       
        if ((fp = fopen(PRIVATEKEY, "r")) == NULL)
        {
                printf("private key path error\n");
                return -1;
        }
        OpenSSL_add_all_algorithms();//密钥有经过口令加密需要这个函数
        if ((privateRsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, (char *)PASS)) == NULL)
        {
                printf("PEM_read_RSAPrivateKey error\n");
                return 0;
        }
        fclose(fp);               

        fp=fopen(encrypt_file_path,"rb");
        if(fp==NULL)
        {
                printf("Can't open file\n");
                return 0;
        }

        while((filelen=fread(outbuffer,1,1024,fp))&gt;0)
        {
                //aes_encrypt(buffer, key, outbuffer);

                //memset(buffer,0,sizeof(buffer));
        }
       
        int rsa_len = RSA_size(publicRsa);

        unsigned char *encryptMsg = (unsigned char *)malloc(rsa_len);
        memset(encryptMsg, 0, rsa_len);
               
        int len = rsa_len - 11;
               
        if (RSA_public_encrypt(len, outbuffer, encryptMsg, publicRsa, RSA_PKCS1_PADDING) &lt; 0)
                printf("RSA_public_encrypt error\n");
        else
        {
                printf("RSA encrypt = %s\n", encryptMsg);
                rsa_len = RSA_size(privateRsa);
                unsigned char *decryptMsg = (unsigned char *)malloc(rsa_len);
                memset(decryptMsg, 0, rsa_len);
          
                int mun =RSA_private_decrypt(rsa_len, encryptMsg, decryptMsg, privateRsa, RSA_PKCS1_PADDING);
       
                if ( mun &lt; 0)
                        printf("RSA_private_decrypt error\n");
                else
                        printf("RSA decrypt = %s\n", decryptMsg);
        }       
       
        RSA_free(publicRsa);
        RSA_free(privateRsa);

        return 0;
}</code></pre>

<p>这里也用之前生成的RSA公私密钥测试;</p>

<p>编译后运行如下图:</p>

<p>RSA解密后也得到了原文;</p>

<p>最后测试RSA签名验签:</p>

<pre>
<code class="language-cpp">//签名验签测试
#define PRIVATE_KEY_PATH ("rsa_private_key.pem")

#define SHA_WHICH      NID_sha256
#define WHICH_DIGEST_LENGTH    SHA256_DIGEST_LENGTH


void printHex(unsigned char *md, int len)
{

    int i = 0;
    for (i = 0; i &lt; len; i++)
    {
      printf("0x%02x, ", md);
    }

    printf("\n");
}

/*读取私钥*/
RSA* ReadPrivateKey(char* p_KeyPath)
{   
    FILE *fp = NULL;
    RSA*priRsa = NULL;

    printf("PrivateKeyPath[%s] \n", p_KeyPath);

    /*打开密钥文件 */
    if(NULL == (fp = fopen(p_KeyPath, "r")))
    {
      printf( "fopen[%s] failed \n", p_KeyPath);
      return NULL;
    }
    /*获取私钥 */
    priRsa = PEM_read_RSAPrivateKey(fp, NULL, NULL,NULL);
    if(NULL == priRsa)
    {
      ERR_print_errors_fp(stdout);
      printf( "PEM_read_RSAPrivateKey\n");
      fclose(fp);
      return NULL;
    }
    fclose(fp);

    return priRsa;
}

int test_RSA_sign(void)
{
    char *data = "china";
    char buf = {0};
    RSA *privKey = NULL;
    int nOutLen = sizeof(buf);
    int nRet = 0;

    //对数据进行sha256算法摘要
    unsigned char md;

    SHA256((unsigned char *)data, strlen(data), md);
    printHex(md, WHICH_DIGEST_LENGTH);

    privKey = ReadPrivateKey(PRIVATE_KEY_PATH);
    if (!privKey)
    {
      ERR_print_errors_fp (stderr);   
      return -1;
    }


    /* 签名 */
    nRet = RSA_sign(SHA_WHICH, md, WHICH_DIGEST_LENGTH, buf, &amp;nOutLen, privKey);
    if(nRet != 1)
    {
      printf("RSA_sign err !!! \n");   
      goto quit;
    }
    printf("RSA_sign len = %d:", nOutLen);
    printHex(buf, nOutLen);


quit:
    RSA_free(privKey);

    return 0;
}

#define PUBLIC_KEY_PATH("rsa_public_key.pem")

#define SHA_WHICH      NID_sha256
#define WHICH_DIGEST_LENGTH    SHA256_DIGEST_LENGTH

/*读取公匙*/
RSA* ReadPublicKey(char* p_KeyPath)
{   
    FILE *fp = NULL;
    RSA *pubRsa = NULL;

    printf("PublicKeyPath[%s]\n", p_KeyPath);

    /*打开密钥文件 */
    if(NULL == (fp = fopen(p_KeyPath, "r")))
    {
      printf( "fopen[%s] \n", p_KeyPath);
      return NULL;
    }
    /*获取公钥 */
    if(NULL == (pubRsa = PEM_read_RSA_PUBKEY(fp, NULL, NULL,NULL)))
    {
      printf( "PEM_read_RSAPrivateKey error\n");
      fclose(fp);
      return NULL;
    }
    fclose(fp);

    return pubRsa;
}

int test_RSA_verify(void)
{
    char *data = "china";
    char buf = {0x72, 0xe8, 0xcc, 0xb0, 0x65, 0xf8, 0x6d, 0x06, 0x49, 0xdc, 0x25, \
    0x8c, 0xb6, 0x04, 0x22, 0xbf, 0x72, 0x18, 0xf4, 0x9d, 0x4f, 0x37, 0x2d, 0x56, 0x62, \
    0x77, 0xaf, 0x97, 0xd6, 0x09, 0xd4, 0x79, 0x25, 0xd9, 0xab, 0x3e, 0x59, 0xe3, 0xf5, \
    0x65, 0x85, 0x84, 0xb3, 0x6e, 0x18, 0x9c, 0x85, 0xed, 0x58, 0xe8, 0x9a, 0x7d, 0x8c, \
    0x9e, 0x6b, 0xd9, 0xd7, 0x79, 0x20, 0xf0, 0x36, 0x8e, 0xe1, 0xbc, 0xdf, 0x55, 0x5c, \
    0xeb, 0xcf, 0xc6, 0x3e, 0x75, 0x37, 0x34, 0x0b, 0xa1, 0x1c, 0x81, 0x25, 0x87, 0x2b, \
    0x97, 0xdb, 0x98, 0x2d, 0xb2, 0xe3, 0xf3, 0x68, 0x38, 0xfd, 0xc2, 0x25, 0x47, 0x3d, \
    0x9a, 0x30, 0x44, 0x35, 0x5b, 0xd6, 0x54, 0xaf, 0xe0, 0xf7, 0x43, 0x82, 0xcf, 0x08, \
    0x10, 0x86, 0x8d, 0x6d, 0xa0, 0x3e, 0x5b, 0xc4, 0x72, 0xb1, 0xe7, 0xb3, 0x49, 0x41, \
    0x04, 0xe5, 0x2b, 0xc7, 0x80,
    };


    RSA *pubKey = NULL;
    int nOutLen = sizeof(buf);
    int nRet = 0;

    //对数据进行sha256算法摘要
    unsigned char md;

    SHA256((unsigned char *)data, strlen(data), md);
    printHex(md, WHICH_DIGEST_LENGTH);


    pubKey = ReadPublicKey(PUBLIC_KEY_PATH);
    if (!pubKey)
    {
      printf("Error: can't load public key");
      return -1;
    }

    /* 验签 */
    nRet = RSA_verify(SHA_WHICH, md, WHICH_DIGEST_LENGTH, buf, nOutLen, pubKey);
    printf("RSA_verify %s(ret=%d).\r\n", (1 == nRet) ? "Success" : "Failed", nRet);

    RSA_free(pubKey);

    return 0;
}</code></pre>

<p>运行结果如下:</p>

<p>可以看到验签通过了。</p>

<p>最后附上测试文件**** Hidden Message *****</p>
</div><script>                                        var loginstr = '<div class="locked">查看本帖全部内容,请<a href="javascript:;"   style="color:#e60000" class="loginf">登录</a>或者<a href="https://bbs.eeworld.com.cn/member.php?mod=register_eeworld.php&action=wechat" style="color:#e60000" target="_blank">注册</a></div>';
                                       
                                        if(parseInt(discuz_uid)==0){
                                                                                                (function($){
                                                        var postHeight = getTextHeight(400);
                                                        $(".showpostmsg").html($(".showpostmsg").html());
                                                        $(".showpostmsg").after(loginstr);
                                                        $(".showpostmsg").css({height:postHeight,overflow:"hidden"});
                                                })(jQuery);
                                        }                </script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script>

okhxyyo 发表于 2020-8-14 20:14

<p>&nbsp;</p>

<p><span style="font-size:16px;">树莓派4B测评汇总:</span></p>

<p><span style="font-size:16px;"><a href="https://bbs.eeworld.com.cn/thread-1137107-1-1.html">https://bbs.eeworld.com.cn/thread-1137107-1-1.html</a></span></p>

vfgvhgh 发表于 2020-8-14 20:27

<p>不错</p>

ly87802541 发表于 2020-8-20 17:25

6666
页: [1]
查看完整版本: 【树莓派4B测评】+openssl库代码测试