ECC加密——C++/OPENssl实现

这篇具有很好参考价值的文章主要介绍了ECC加密——C++/OPENssl实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、介绍:

因为最近设计一些密钥交换相关的协议,做了很多调研,和学习。本来想直接使用ECC完成密钥交换协议,但是现存的很多代码都是基于ECDH的,这完全不是基于ECC加密的。尝试了很久之后终于自己手写了一份加密方案出来,为了方便更好的加解密,我封装成数组进行了,可自行更改。属实不易,全网独一份,希望大家点个赞,拷贝请声明。

二、代码:

请容我简单介绍一下思路:

其实在ECC相关开源库里可以看出并没有直接的加密解密。所以的咱们如何实现加密呢——点乘,m = a*G*c,a是私钥,c是明文,m是密文,a为私钥,G为基点,如果已知m、G,就无法破解获得c。如果解密只需要m乘a的逆。再说一些细节:

1:c是字符串,想要实现乘必须先将c转换成一种大数,再用大数点乘;

2:a的逆如何求,我们要先获得椭圆曲线的阶n,a*x % n =1,x为a的逆。所以先获得阶n,再用大数库求逆。

3:为了更方便的输出,我将所有大数转成16进制输出,在很多场景中不需要解密,我们可以采用div参数设置输出16进制字符串的长度。

4:点赞、收藏,不然以后这么良心的作品要收费了!

 

ECDH.cpp

void myECC::encrypt(std::string key, std::vector<std::string> &plaintext, std::vector<std::string> &strCipher_list, unsigned long long size, int div){
    BIGNUM *key_big = BN_new();
    char *hex_pk;
    BN_dec2bn(&key_big, (char *)key.data());//随机数转换成大数
    //建立椭圆曲线
    EC_KEY *ecdh = EC_KEY_new();
    EC_GROUP *group;
    EC_POINT *point_mul_aG, *point_mul_aGp;

    const EC_POINT *generator;
    ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);//NID_secp521r1
    group = (struct ec_group_st *) EC_KEY_get0_group(ecdh);
    point_mul_aG = EC_POINT_new(group);
    point_mul_aGp = EC_POINT_new(group);
    //获得基向量
    generator = EC_GROUP_get0_generator(group);
    //获得a*G
    EC_POINT_mul(group, point_mul_aG, NULL, generator, key_big, NULL);
    if(div) {
        for (int i = 0; i < size; ++i) {
            BN_dec2bn(&key_big, (char *) plaintext[i].data());
            EC_POINT_mul(group, point_mul_aGp, NULL, point_mul_aG, key_big, NULL);
            //hex_pk = EC_POINT_point2hex(group, point_mul_aGp, POINT_CONVERSION_COMPRESSED, NULL);
            EC_POINT_point2bn(group, point_mul_aGp, POINT_CONVERSION_COMPRESSED, key_big, NULL);
            hex_pk = BN_bn2dec(key_big);

            strCipher_list.push_back(((std::string) hex_pk).substr(0, div));
        }
    }else{
        for (int i = 0; i < size; ++i) {
            BN_dec2bn(&key_big, (char *) plaintext[i].data());
            EC_POINT_mul(group, point_mul_aGp, NULL, point_mul_aG, key_big, NULL);
            //hex_pk = EC_POINT_point2hex(group, point_mul_aGp, POINT_CONVERSION_COMPRESSED, NULL);
            EC_POINT_point2bn(group, point_mul_aGp, POINT_CONVERSION_COMPRESSED, key_big, NULL);
            hex_pk = BN_bn2dec(key_big);
            strCipher_list.push_back((std::string) hex_pk);
        }
    }

    EC_GROUP_free(group);
    EC_POINT_free(point_mul_aG);
    EC_POINT_free(point_mul_aGp);


};



void myECC::decrypt(std::string key, std::vector<std::string> &plaintext, std::vector<std::string> &strCipher_list, unsigned long long size, int div) {

    BIGNUM *key_big = BN_new();
    BIGNUM *data_big = BN_new();
    char *hex_pk;
    BN_dec2bn(&key_big, (char *) key.data());//随机数转换成大数
    //建立椭圆曲线
    EC_KEY *ecdh = EC_KEY_new();
    EC_GROUP *group;
    EC_POINT *point_mul_aG, *point_mul_aGp;
    ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);//NID_secp521r1
    group = (struct ec_group_st *) EC_KEY_get0_group(ecdh);
    point_mul_aG = EC_POINT_new(group);
    point_mul_aGp = EC_POINT_new(group);
    //获得阶N
    BIGNUM *order, *key_inverse;
    order = BN_new();
    key_inverse = BN_new();
    EC_GROUP_get_order(group, order,NULL);
    //求逆
    BN_mod_inverse( key_inverse,key_big, order,NULL);
    //EC_POINT_mul(group, point_mul_aG, NULL, generator, key_big, NULL);
    if(div){
        for (int i = 0; i < size; ++i) {

            char *str_a = (char *) strCipher_list[i].data();
            BN_dec2bn(&data_big, str_a);
            EC_POINT_bn2point(group, data_big, point_mul_aG, NULL);

            EC_POINT_mul(group, point_mul_aGp, NULL, point_mul_aG, key_inverse, NULL);
            //hex_pk = EC_POINT_point2hex(group, point_mul_aGp, POINT_CONVERSION_COMPRESSED, NULL);
            EC_POINT_point2bn(group, point_mul_aGp, POINT_CONVERSION_COMPRESSED, data_big, NULL);//将点转换成大数。
            hex_pk = BN_bn2dec(data_big);//将大数转换成整数字符串。
            plaintext.push_back(((std::string) hex_pk).substr(0, div));
        }
    } else{
            for (int i = 0; i < size; ++i) {
                char *str_a = (char *) strCipher_list[i].data();
                BN_dec2bn(&data_big, str_a);
                EC_POINT_bn2point(group, data_big, point_mul_aG, NULL);

                EC_POINT_mul(group, point_mul_aGp, NULL, point_mul_aG, key_inverse, NULL);
                //hex_pk = EC_POINT_point2hex(group, point_mul_aGp, POINT_CONVERSION_COMPRESSED, NULL);
                EC_POINT_point2bn(group, point_mul_aGp, POINT_CONVERSION_COMPRESSED, data_big, NULL);//将点转换成大数。
                hex_pk = BN_bn2dec(data_big);//将大数转换成整数字符串。
                plaintext.push_back((std::string) hex_pk);
            }
    }
    EC_GROUP_free(group);
    EC_POINT_free(point_mul_aG);
    EC_POINT_free(point_mul_aGp);


}

ECDH.h文章来源地址https://www.toymoban.com/news/detail-547004.html

//
// Created by admin on 2022/10/9.
//

#ifndef BPIR_ECDH_H
#define BPIR_ECDH_H
#include <openssl/pem.h>
#include <openssl/ecdh.h>
#include <iostream>
#include <sstream>
#include <vector>
namespace aes{}
class myECC {
public:
    void encrypt(std::string key, std::vector<std::string> &plaintext, std::vector<std::string> &strCipher_list, unsigned long long size,  int div = 0);
    void decrypt(std::string key, std::vector<std::string> &plaintext, std::vector<std::string> &strCipher_list, unsigned long long size,  int div = 0);
};


#endif //BPIR_ECDH_H

到了这里,关于ECC加密——C++/OPENssl实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 如何选择 SSL证书的加密算法:RSA、ECC、SM2

    沃通CA可以提供这三种加密算法的SSL证书。 RSA、ECC、SM2。这也是目前 SSL证书涉及到的 3 种加密算法。 按照目前的使用普遍度:RSA ECC SM2 SSL证书在提交申请的时候,就会需要选择加密算法,目前使用较多的依然是 RSA,或者 RSA 和 ECC 配合使用。在某些情况下会选择 SM2 算法。

    2023年04月09日
    浏览(48)
  • c++中的OpenSSL加密(对称与非对称)

    使用OpenSSL实现安全加密通信的服务器与客户端项目 https://gitee.com/lzhiqiang1999/sec-tans 欢迎star 1 特点: 不可逆 抗碰撞性强 不同的数据拥有不同的哈希值, 相同的数据哈希值是相同的 原始数据有细微的变化, 哈希值的变化是非常大的 通过哈希函数将原始数据进行运算, 得到的哈希

    2024年02月13日
    浏览(33)
  • 使用 OpenSSL 扩展来实现公钥和私钥加密

    首先,你需要生成一对公钥和私钥。可以使用 OpenSSL 工具来生成: 1、生成私钥 2、从私钥生成公钥: 现在你有了一个私钥( private_key.pem )和一个对应的公钥( public_key.pem )。下面是如何在 PHP 中使用它们进行加密和解密: 3、检测是否支付OPENSSL,或用phpinfo(); 上述代码中,

    2024年02月03日
    浏览(39)
  • 调库实现简单的AES,ECC,SHA-256,支持文本(txt)、图片(png)、音频(mp4)

    一、设计要求 在设计和实现系统时,选择调用了以下密码库: Bouncy Castle (BC): 用于实现椭圆曲线密码学(ECC)算法,确保系统安全传输密钥的过程。 Java Cryptography Architecture (JCA): 用于实现对称加密算法(如AES)和SHA-256哈希算法等,提供主流密码学算法的支持。 支持的数据类

    2024年01月25日
    浏览(43)
  • ECC功能简述及其原理

    1、NOR的特点是芯片内执行(XIP,eXecute In Place),这样应用程序可以直接在flash闪存内运行,不必再把代码读到系统RAM中。优点是可以直接从FLASH中运行程序,但是工艺复杂,价格比较贵,NOR的传输效率很高,在1~4MB的小容量时具有很高的成本效益,但是很低的写入和擦除速度大大影响了它

    2024年02月05日
    浏览(41)
  • ECC椭圆曲线入门

    https://web3study.club/ ECC(Ellipse Curve Cryptography)又称椭圆曲线密码体制、椭圆曲线加密算法等。 椭圆曲线加密算法在比特币、区块链上有着广泛的应用。 公式: y^2 = x^3 + ax + b 这里使用简单易懂的方式对大家介绍这部分内容,让大家有个简单的理解 公私钥加密内容​ 公钥未公开部

    2023年04月09日
    浏览(31)
  • 流量加密之OpenSSL反弹加密

    目录 1、OpenSSL 简介 2、使用 OpenSSL 反弹加密 shell 3、使用wireshark抓包验证 4、搭建 HTTPS Server OpenSSL 是一个强大的、商业级的、功能齐全的开源工具包,用于 TLS(以前称为 SSL)、DTLS 和 QUIC(目前仅限客户端)协议,协议实现基于全功能通用加密库,也可以单独使用,还包括一

    2024年01月16日
    浏览(35)
  • DDR5 内存ECC

    针对DDR5,已经写了很多文章来分析,但最近工作中碰到一个问题, 同一个channel里的CB是不是可以任意互换?  让我对DDR5的ECC功能有一些疑问,查了下资料发现这里面水挺深,ECC居然还有好几种? DDR作为目前主板上带宽最高的设备和协议,误码率当然是其中最重要的参数之一

    2024年02月15日
    浏览(25)
  • ECC算法学习(一)算法公式

    ECC全称为“Ellipse Curve Ctyptography”,是一种基于椭圆曲线数学的公开密钥加密算法。与传统的基于大质数分解难题的加密算法不同,该加密方式基于 “离散对数” 这种数学难题。 椭圆曲线在密码学中的使用是在1985年由Neal Koblitz和Victor Miller分别独立提出的。 优缺点 优点:

    2024年04月22日
    浏览(53)
  • 数字签名验签 — ECC算法

    ​ 前段时间,项目上有需求对于重要文件的传输接收时,接收端需要对文件进行安全校验,采用数字签名的方式确保数据来源的安全性以及数据完整性。之前未接触过密码安全方面的知识,现将实施过程中所遇所学记录下来~ ​ 本文将按照以下知识内容来记录: ​ 1 数字签

    2024年02月05日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包