首页 > 其他分享 >android开发使用openssl3.3.2加解密国密sm2代码实现

android开发使用openssl3.3.2加解密国密sm2代码实现

时间:2024-11-26 19:00:12浏览次数:7  
标签:PKEY openssl3.3 ectx 加解密 sm2 char EVP NULL

#include "openssl/rsa.h"
#include "openssl/pem.h"
#include "openssl/err.h"
#include "openssl/evp.h"
#include "openssl/ec.h"
#include <string>
#include <unistd.h>
#include "openssl_sm2.hpp"
#include "log/android_log.h"

std::string GetErrorStr() {
    unsigned long er = 0;
    char erbuf[512] = {0};
    size_t erlen = 512;
    er = ERR_get_error();
    ERR_error_string_n(er, erbuf, erlen);
    return std::string(erbuf, erlen);
}

//加密
int my_sm2encrpt(std::string keystr, unsigned char *sourStr, int cStrlen, unsigned char *enStr) {
    BIO *bp = NULL;
    EVP_PKEY *pkey = NULL;
    EVP_PKEY_CTX *ectx = NULL;
    size_t cEnStrlen;
    char *cEnStr = NULL;
    char *chPublicKey = const_cast<char *>(keystr.c_str());
    int ret = -1;
    if ((bp = BIO_new_mem_buf(chPublicKey, -1)) == NULL) {
        ALOGE("BIO_new_mem_buf failed!\n");
        return 0;
    }
    pkey = PEM_read_bio_PUBKEY(bp, NULL, NULL, NULL);
    BIO_free_all(bp);
//     要去掉,不然执行EVP_PKEY_encrypt_init会报错返回-2
//    if ((EVP_PKEY_set_type(pkey, EVP_PKEY_SM2)) != 1) {
//        goto clean_up;
//    }

    if (!(ectx = EVP_PKEY_CTX_new(pkey, NULL))) {
        goto clean_up;
    }

    ret = EVP_PKEY_encrypt_init(ectx);
    ALOGI("EVP_PKEY_encrypt_init ret=%d\n", ret);
    if (ret != 1) {
        ALOGI("EVP_PKEY_encrypt_init error=%s\n", GetErrorStr().c_str());
        goto clean_up;
    }

    if ((EVP_PKEY_encrypt(ectx, NULL, &cEnStrlen, reinterpret_cast<unsigned char *>(sourStr),
                          (size_t) (cStrlen))) != 1) {
        goto clean_up;
    }
    if (!(cEnStr = (char *) malloc(cEnStrlen))) {
        goto clean_up;
    }

    if ((EVP_PKEY_encrypt(ectx, reinterpret_cast<unsigned char *>(cEnStr), &cEnStrlen,
                          reinterpret_cast<unsigned char *>(sourStr), cStrlen)) != 1) {
        goto clean_up;
    }
    ALOGI("enStrLen2: %ld\n", cEnStrlen);
    memcpy(enStr, cEnStr, cEnStrlen);
    return (int) (cEnStrlen);

    clean_up:

    if (pkey) {
        EVP_PKEY_free(pkey);
    }
    if (ectx) {
        EVP_PKEY_CTX_free(ectx);
    }
    if (cEnStr) {
        free(cEnStr);
    }
    return 0;
}

//解密
int dencryptStr(std::string keystr, unsigned char *cEnStr, int cEnstrlen, unsigned char *deStr) {
    BIO *priBp = NULL;
    EVP_PKEY *mSm2PriKey;
    EVP_PKEY_CTX *ectx = NULL;
    size_t cDeStrlen = 0;
    char *cDeStr = NULL;
    //create pri key
    char *chPrilicKey = const_cast<char *>(keystr.c_str());
    if ((priBp = BIO_new_mem_buf(chPrilicKey, -1)) == NULL) {
        ALOGE("BIO_new_mem_buf failed!\n");
    }
    mSm2PriKey = PEM_read_bio_PrivateKey(priBp, NULL, NULL, NULL);
    BIO_free_all(priBp);
    if (NULL == mSm2PriKey) {
        ERR_load_crypto_strings();
        char errBuf[512];
        ERR_error_string_n(ERR_get_error(), errBuf, sizeof(errBuf));
        ALOGE("load sm2 private key failed[%s]\n", errBuf);
    }
    //解密
//     要去掉,不然执行EVP_PKEY_encrypt_init会报错返回-2
//    if ((EVP_PKEY_set_type(mSm2PriKey, EVP_PKEY_SM2)) != 1) {
//        ALOGE("EVP_PKEY_set_alias_type failed!\n");
//    }

    if (!(ectx = EVP_PKEY_CTX_new(mSm2PriKey, NULL))) {
        ALOGE("EVP_PKEY_CTX_new failed!\n");
    }
    if ((EVP_PKEY_decrypt_init(ectx)) != 1) {
        ALOGE("EVP_PKEY_decrypt_init failed!\n");
    }
    if ((EVP_PKEY_decrypt(ectx, NULL, &cDeStrlen, reinterpret_cast<unsigned char *>(cEnStr),
                          cEnstrlen)) != 1) {
        ALOGE("EVP_PKEY_decrypt failed!\n");
        ERR_load_crypto_strings();
        char errBuf[512];
        ERR_error_string_n(ERR_get_error(), errBuf, sizeof(errBuf));
        ALOGE("EVP_PKEY_decrypt[%s]\n", errBuf);
    }
    if (!(cDeStr = (char *) malloc(cDeStrlen))) {
        ALOGE(" (unsigned char *)malloc(cDeStrlen)) failed!\n");
    }
    if ((EVP_PKEY_decrypt(ectx, reinterpret_cast<unsigned char *>(cDeStr), &cDeStrlen,
                          reinterpret_cast<unsigned char *>(cEnStr), cEnstrlen)) != 1) {
        ALOGE(" EVP_PKEY_decrypt failed!\n");
    }
    ALOGI("cDeStrlen:%d\n", cDeStrlen);
    memcpy(deStr, cDeStr, cDeStrlen);
    EVP_PKEY_CTX_free(ectx);
    free(cDeStr);
    return cDeStrlen;
}
//测试代码
int test_my_sm2() {
    ALOGI("test_my_sm2 start");
    //1.首先PC电脑上安装openssl客户端,然后执行下面命令生成公钥-私钥
    //2.生成私钥:openssl ecparam -outform pem -out sm2PriKey.pem -name sm2 -genkey
    //3.生成公钥:openssl ec -in sm2PriKey.pem -pubout -out sm2PubKey.pem
    //4.文本记事本分别打开私钥文件sm2PriKey.pem和公钥文件sm2PriKey.pem,分别复制里面的值给sm2PriKeyStr和sm2PubKeyStr变量
    std::string sm2PriKeyStr = "-----BEGIN SM2 PARAMETERS-----\n"
                               "BggqgRzPVQGCLQ==\n"
                               "-----END SM2 PARAMETERS-----\n"
                               "-----BEGIN PRIVATE KEY-----\n"
                               "MIGIAgEAMBQGCCqBHM9VAYItBggqgRzPVQGCLQRtMGsCAQEEIAeYlDHP36Z3ZQTZ\n"
                               "PwIQSkSU7Ut9uteRHGiGlpxiPGzroUQDQgAEOw+Byzd+Vu31TVCuOQFjewcL4jt4\n"
                               "ShOxGNS0sQaF6g1sBvRwnUbzfaGXdhmkllxCvygGxeX1TF/zI/MQNzgHjg==\n"
                               "-----END PRIVATE KEY-----\n";
    std::string sm2PubKeyStr = "-----BEGIN PUBLIC KEY-----\n"
                               "MFowFAYIKoEcz1UBgi0GCCqBHM9VAYItA0IABDsPgcs3flbt9U1QrjkBY3sHC+I7\n"
                               "eEoTsRjUtLEGheoNbAb0cJ1G832hl3YZpJZcQr8oBsXl9Uxf8yPzEDc4B44=\n"
                               "-----END PUBLIC KEY-----\n";

    unsigned char sm2_en[512], sm2_de[512];
    int sm2enStrLen, sm2deStrLen;


    unsigned char source[20] = {0x41, 0x12, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11,
                                0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20};

    sm2enStrLen = my_sm2encrpt(sm2PubKeyStr, source, 20, sm2_en);
    ALOGI("sm2enStrLen :%d \n", sm2enStrLen);
    std::string sm2_en_str;
    char buf[100];
    for (int i = 0; i < sm2enStrLen; i++) {
        snprintf(buf, 100, "0x%02x ", sm2_en[i]);
        sm2_en_str.append(buf);
    }
    ALOGI("sm2_en_str :%s\n", sm2_en_str.c_str());

    sm2deStrLen = dencryptStr(sm2PriKeyStr, sm2_en, sm2enStrLen, sm2_de);
    ALOGI("sm2deStrLen :%d \n", sm2deStrLen);
    std::string sm2_de_str;
    for (int i = 0; i < sm2deStrLen; i++) {
        snprintf(buf, 100, "0x%x ", sm2_de[i]);
        sm2_de_str.append(buf);
    }
    ALOGI("sm2_de_str :%s\n", sm2_de_str.c_str());

    ALOGI("test_my_sm2 end");
    return 0;
}

标签:PKEY,openssl3.3,ectx,加解密,sm2,char,EVP,NULL
From: https://www.cnblogs.com/yongfengnice/p/18570798

相关文章

  • C#.NET CORE SM2国密PKCS12格式私钥证书解析
    C#.NETCORE SM2国密PKCS12格式私钥证书解析、加载、签名、加密。 PKCS12格式私钥证书,和常见到.sm2文件私钥证书不同。它虽是BASE64编码的字符串,但不能用解析.sm2文件的方法解析。上来还是nuget下载引用 Portable.BouncyCastle库。工具类 GmUtil:usingOrg.BouncyCastle......
  • SM2268XT2量产工具找到了,SM2268XT2量产工具下载,支持B58R闪存颗粒开卡,SM2268XT2开卡工
    前一阵买了一个固态硬盘,主控是SM2268XT2,闪存颗粒是B58R的,由于自己之前量产过SM2263XT主控,所以这次也想玩一下量产。找了半天,才发现这个主控目前还没有公开的SM2268XT2量产工具下载。就在快要放弃的时候,在网上查到量产部落发布了慧荣SM2268XT2主控支持YMTC_WDS闪存的量产工具,......
  • 常用加解密算法详解与应用指南
    1.引言加解密算法是保证数据安全的基础技术,无论是在数据传输、存储,还是用户身份验证中,都起着至关重要的作用。随着互联网的发展和信息安全威胁的增加,了解并掌握常用的加解密算法已经成为开发者和安全从业者的必修课。本文将详细介绍几种常见的加解密算法,包括对称加密、非......
  • iOS 在OC 中使用 AEC 的 ECB、CTR模式加解密
    实用实测过的代码。 AEC加解密网上一大把,简单列举一下。CTR模式,搜索了好多,试用了好几个都是代码不完全参数不对造成无法正常运行加解密。不同模式引用了不同的系统库路径。 调整加解密,修改参数 operation:kCCDecrypt/ kCCEncryptAECCTR模式解密#import<CommonCryp......
  • 【Mybatis】Mybatis拦截器+注解,实现敏感数据自动加解密
    一:背景     今天,公司新要求对数据库的敏感数据进行加密,对手机号、身份证号、姓名等一些敏感数据进行加密处理,要求:    1.通过程序实现数据加密解密(快速便捷,尽量减少对原先代码的修改)    2.可以通过sql查询对数据进行解密(通过密钥直接对数据库......
  • 七彩虹SL300固态硬盘不认盘修复,SM2256K量产工具,支持AD,3A,18,A3,61,25颗粒H27QFG8PDM
    固态硬盘里采用慧荣主控的品牌很多,其中常见的慧荣主控型号有SM2246XT、SM2256K、SM2258XT、SM2259XT、SM2259XT2、SM2259XT3、SM2263XT等等,这些主控的固态硬盘要是坏了,在保质期里的可以返厂维修,如果过保了,我们还是有办法自己修复的,方法就是从量产部落下载量产工具,用量产工具来......
  • SM2244LT量产工具经验分享,SM2244LT量产工具下载,SM2244LT开卡教程
    一、注意事项1、个人观点,仅供参考2、开卡后无法恢复数据二、开卡前的准备1、坏固态硬盘一个(确认主控芯片是慧荣SM2244LT)2、尖头镊子(细铜线、铁丝等能导电的金属都行,塑料的不行)3、一台电脑(可以是笔记本或台式机,台式机最好不要用后置USB)4、转接卡(可以是开卡板、硬盘盒等,建议用ASM1153......
  • java 实现AES的CBC、CFB、OFB加解密
    1.CBC(CipherBlockChaining,密码分组链接模式)概述CBC模式是一种常见的块密码工作模式,通过将每个明文块与前一个密文块进行异或操作,再进行加密,从而增强数据的安全性。工作原理初始向量(IV,InitializationVector):CBC模式需要一个随机生成的IV来确保相同明文在不同加密过......
  • mtgsig 1.2 纯算加解密
    mtgsig1.2 {   "a1":"1.2",//固定   "a2":1726748343771,//动态时间戳   "a3":"1726748343765IYKMICE60e593ce0a815b08d658526270cd17d61109",//dfpid可以是本地生成也可以调用接口获取   "a4":"fc356f4601dbbe9646......
  • 这才是我想要的PCIe 5.0 SSD!慧荣SM2508主控首测:读写满血 还不烫手
    市面上现有的PCIe5.0SSD几乎都采用了群联E26主控,不但读写速度达不到满血标准,最高也就12GB/s,功耗和发热还特别高,经常需要主动风扇散热。英韧IG5666性能好了不少,基本可以跑满,但是发热仍然太高,因为它俩都是台积电12nm。慧荣已经多次展示过他们的方案SM2580,一方面性能满血,一方面发......