首页 > 编程语言 >加密算法

加密算法

时间:2023-04-15 21:23:09浏览次数:37  
标签:RSA pub rsa char key include 加密算法

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

#include <openssl/rsa.h>
#include <openssl/err.h>
#include <openssl/objects.h>

#pragma comment(lib,"libssl.lib")
#pragma comment(lib,"libcrypto.lib")

namespace dakuang {}

void printHex(const unsigned char* pBuf, int nLen)
{
    for (int i = 0; i < nLen; ++i)
    {
        printf("%02x", pBuf[i]);
    }
    printf("\n");
}


#include <iostream>
#include <memory>

struct Sample
{
    Sample() {
        std::cout << "Sample\n";
    }
    ~Sample() {
        std::cout << "~Sample\n";
    }
    int a{ 1 };
};

void deleter(Sample* x)
{
    std::cout << "Custom Deleter\n";
    delete[] x;
}


#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

#include <openssl/rsa.h>
#include <openssl/err.h>
#include <openssl/x509.h>
#include <string.h>
#include <openssl/rsa.h>
#include <openssl/aes.h>


#include <cassert>  
#include <string>    
#include <vector>    
#include "openssl/md5.h"    
#include "openssl/sha.h"    
#include "openssl/des.h"    
#include "openssl/rsa.h"    
#include "openssl/pem.h"    
// ---- rsa非对称加解密 ---- //    
#define KEY_LENGTH  2048             // 密钥长度  
#define PUB_KEY_FILE "pubkey.pem"    // 公钥路径  
#define PRI_KEY_FILE "prikey.pem"    // 私钥路径  

// 函数方法生成密钥对   
void generateRSAKey(std::string strKey[2])
{
    // 公私密钥对    
    size_t pri_len;
    size_t pub_len;
    char* pri_key = NULL;
    char* pub_key = NULL;

    // 生成密钥对    
    RSA* keypair = RSA_generate_key(KEY_LENGTH, RSA_3, NULL, NULL);

    BIO* pri = BIO_new(BIO_s_mem());
    BIO* pub = BIO_new(BIO_s_mem());

    PEM_write_bio_RSAPrivateKey(pri, keypair, NULL, NULL, 0, NULL, NULL);
    PEM_write_bio_RSAPublicKey(pub, keypair);

    // 获取长度    
    pri_len = BIO_pending(pri);
    pub_len = BIO_pending(pub);

    // 密钥对读取到字符串    
    pri_key = (char*)malloc(pri_len + 1);
    pub_key = (char*)malloc(pub_len + 1);

    BIO_read(pri, pri_key, pri_len);
    BIO_read(pub, pub_key, pub_len);

    pri_key[pri_len] = '\0';
    pub_key[pub_len] = '\0';

    // 存储密钥对    
    strKey[0] = pub_key;
    strKey[1] = pri_key;

    // 存储到磁盘(这种方式存储的是begin rsa public key/ begin rsa private key开头的)  
    FILE* pubFile = fopen(PUB_KEY_FILE, "w");
    if (pubFile == NULL)
    {
        //assert(false);
        return;
    }
    fputs(pub_key, pubFile);
    fclose(pubFile);

    FILE* priFile = fopen(PRI_KEY_FILE, "w");
    if (priFile == NULL)
    {
        //assert(false);
        return;
    }
    fputs(pri_key, priFile);
    fclose(priFile);

    // 内存释放  
    RSA_free(keypair);
    BIO_free_all(pub);
    BIO_free_all(pri);

    free(pri_key);
    free(pub_key);
}

// 命令行方法生成公私钥对(begin public key/ begin private key)  
// 找到openssl命令行工具,运行以下  
// openssl genrsa -out prikey.pem 1024   
// openssl rsa - in privkey.pem - pubout - out pubkey.pem  

// 公钥加密    
std::string rsa_pub_encrypt(const std::string& clearText, const std::string& pubKey)
{
    std::string strRet;
    RSA* rsa = NULL;
    BIO* keybio = BIO_new_mem_buf((unsigned char*)pubKey.c_str(), -1);
    // 此处有三种方法  
    // 1, 读取内存里生成的密钥对,再从内存生成rsa  
    // 2, 读取磁盘里生成的密钥对文本文件,在从内存生成rsa  
    // 3,直接从读取文件指针生成rsa  
    RSA* pRSAPublicKey = RSA_new();
    rsa = PEM_read_bio_RSAPublicKey(keybio, &rsa, NULL, NULL);

    int len = RSA_size(rsa);
    char* encryptedText = (char*)malloc(len + 1);
    memset(encryptedText, 0, len + 1);

    // 加密函数  
    int ret = RSA_public_encrypt(clearText.length(), (const unsigned char*)clearText.c_str(), (unsigned char*)encryptedText, rsa, RSA_PKCS1_PADDING);
    if (ret >= 0)
        strRet = std::string(encryptedText, ret);

    // 释放内存  
    free(encryptedText);
    BIO_free_all(keybio);
    RSA_free(rsa);

    return strRet;
}

// 私钥解密    
std::string rsa_pri_decrypt(const std::string& cipherText, const std::string& priKey)
{
    std::string strRet;
    RSA* rsa = RSA_new();
    BIO* keybio;
    keybio = BIO_new_mem_buf((unsigned char*)priKey.c_str(), -1);

    // 此处有三种方法  
    // 1, 读取内存里生成的密钥对,再从内存生成rsa  
    // 2, 读取磁盘里生成的密钥对文本文件,在从内存生成rsa  
    // 3,直接从读取文件指针生成rsa  
    rsa = PEM_read_bio_RSAPrivateKey(keybio, &rsa, NULL, NULL);

    int len = RSA_size(rsa);
    char* decryptedText = (char*)malloc(len + 1);
    memset(decryptedText, 0, len + 1);

    // 解密函数  
    int ret = RSA_private_decrypt(cipherText.length(), (const unsigned char*)cipherText.c_str(), (unsigned char*)decryptedText, rsa, RSA_PKCS1_PADDING);
    if (ret >= 0)
        strRet = std::string(decryptedText, ret);

    // 释放内存  
    free(decryptedText);
    BIO_free_all(keybio);
    RSA_free(rsa);

    return strRet;
}

int main()
{
//    // 1. 产生RSA密钥对
//    // 产生512字节公钥指数为RSA_F4的密钥对,公钥指数有RSA_F4和RSA_3两种
//    // 我不清楚它们的区别,就随便选定RSA_F4
//    // 可以使用RSA_print_fp()看看RSA里面的东西
//    RSA* ClientRsa = RSA_generate_key(2048, RSA_F4, NULL, NULL);
//
//    // ---------
//    // 2. 从RSA结构中提取公钥到BUFF,以便将它传输给对方
//    // 512位的RSA其公钥提出出来长度是74字节,而私钥提取出来有超过300字节
//    // 为保险起见,建议给它们预留一个512字节的空间
//    unsigned char PublicKey[5120];
//    unsigned char* PKey = PublicKey; // 注意这个指针不是多余,是特意要这样做的,
//    int PublicKeyLen = i2d_RSAPublicKey(ClientRsa, &PKey);
//
//    // 不能采用下面的方法,因为i2d_RSAPublicKey()会修改PublicKey的值
//    // 所以要引入PKey,让它作为替死鬼
//    // unsigned char *PublicKey = (unsigned char *)malloc(512);
//    // int PublicKeyLen = i2d_RSAPublicKey(ClientRsa, &PublicKey);
//
//    // 逐个字节打印PublicKey信息
//    printf("PublicKeyBuff, Len=%d\n", PublicKeyLen);
//    for (int i = 0; i < PublicKeyLen; i++)
//    {
//        printf("0x%02x, ", *(PublicKey + i));
//    }
//    printf("\n");
//
//
//    // ---------
//    // 3. 跟据上面提出的公钥信息PublicKey构造一个新RSA密钥(这个密钥结构只有公钥信息)
//    PKey = PublicKey;
//    RSA* EncryptRsa = d2i_RSAPublicKey(NULL, (const unsigned char**)&PKey, PublicKeyLen);
//
//    // ---------
//    // 4. 使用EncryptRsa加密数据,再使用ClientRsa解密数据
//    // 注意, RSA加密/解密的数据长度是有限制,例如512位的RSA就只能最多能加密解密64字节的数据
//    // 如果采用RSA_NO_PADDING加密方式,512位的RSA就只能加密长度等于64的数据
//    // 这个长度可以使用RSA_size()来获得
//    unsigned char InBuff[640], OutBuff[640];
//
//    strcpy((char*)InBuff, "1234567890abcdefghiklmnopqrstuvwxyz.\
//1234567890abcdefghiklmnopqrstuvwxyz.\
//1234567890abcdefghiklmnopqrstuvwxyz.\
//1234567890abcdefghiklmnopqrstuvwxyz.\
//1234567890abcdefghiklmnopqrstuvwxyz.\
//1234567890abcdefghiklmnopqrstuvwxyz.\
//1234567890abcdefghiklmnopqrstuvwxyz.\
//1234567890abcdefghiklmnopqrstuvwxyz.\
//1234567890abcdefghiklmnopqrstuvwxyz.\
//1234567890abcdefghiklmnopqrstuvwxyz.\
//1234567890abcdefghiklmnopqrstuvwxyz.\
//1234567890abcdefghiklmnopqrstuvwxyz.");
//    RSA_public_encrypt(640, (const unsigned char*)InBuff, OutBuff, EncryptRsa, RSA_NO_PADDING); // 加密
//
//    memset(InBuff, 0, sizeof(InBuff));
//    RSA_private_decrypt(640, (const unsigned char*)OutBuff, InBuff, ClientRsa, RSA_NO_PADDING); // 解密
//    printf("RSADecrypt OK: %s \n", InBuff);
//
//
//    //// ----------
//    //// 5. 利用随机32字节Seed来产生256位的AES密钥对
//    //unsigned char Seed[32]; // 可以采用Rand()等方法来构造随机信息
//    //AES_KEY AESEncryptKey, AESDecryptKey;
//    //AES_set_encrypt_key(Seed, 256, &AESEncryptKey);
//    //AES_set_decrypt_key(Seed, 256, &AESDecryptKey);
//
//    //// ----------
//    //// 6. 使用AES密钥对来加密/解密数据
//    //// 注意,256位的AES密钥只能加密/解密16字节长的数据
//    //strcpy((char*)InBuff, "a1b2c3d4e5f6g7h8?");
//    //AES_encrypt(InBuff, OutBuff, &AESEncryptKey);
//
//    //memset(InBuff, 0, sizeof(InBuff));
//    //AES_decrypt(OutBuff, InBuff, &AESDecryptKey);
//    //printf("AESDecrypt OK: %s \n", InBuff);
//
//
//    // ----------
//    // 7. 谨记要释放RSA结构
//    RSA_free(ClientRsa);
//    RSA_free(EncryptRsa);

    std::string encryptText;
    std::string encryptHexText;
    std::string decryptText;
    // 原始明文    
    std::string srcText = "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
      // rsa    
    std::cout << "=== rsa加解密 ===" << std::endl;
    std::string key[2];
    generateRSAKey(key);
    std::cout << "公钥: " << std::endl;
    std::cout << key[0] << std::endl;
    std::cout << key[0].length() << std::endl;

    std::cout << "私钥: " << std::endl;
    std::cout << key[1] << std::endl;
    encryptText = rsa_pub_encrypt(srcText, key[0]);
    std::cout << "加密字符: " << std::endl;
    std::cout << encryptText << std::endl;
    decryptText = rsa_pri_decrypt(encryptText, key[1]);
    std::cout << "解密字符: " << std::endl;
    std::cout << decryptText << std::endl;

    return(0);
}

 

标签:RSA,pub,rsa,char,key,include,加密算法
From: https://www.cnblogs.com/yewu1/p/17321908.html

相关文章

  • Paillier半同态加密算法及C++实现
    Paillier半同态加密系统详解及C++实现Paillier半同态加密系统详解及C++实现一、Paillier同态加密算法1.1基本概念1.2算法思路1.3加解密过程密钥生成KeyGeneration加密Encryption解密Decryption二、C++实现2.1实验环境Linux版本编译器版本2.2......
  • ssh服务支持弱加密算法
    详情描述:远程SSH服务器配置为使用arcfour流密码或无任何密码。RFC4253不建议使用arcfour弱算法。https://tools.ietf.org/html/rfc4253#section-6.3解决方案:解决方法:*在SSH会话中仅使用CTR模式加密算法,如AES-CTR。https://tools.ietf.org/html/rfc4253#section-6.3方案......
  • golang CVE-2016-2183漏洞,https需要添加tls设置加密算法CipherSuites白名单,将弱加密算
    golangCVE-2016-2183漏洞,https需要添加tls设置加密算法白名单,将弱加密算法DES和3DES去掉。服务端样例代码packagemainimport("crypto/tls""fmt""net/http")funchandler(writerhttp.ResponseWriter,request*http.Request){fmt.Fprintf(wri......
  • 对称加密算法和非对称加密算法
    对称加密对称加密,是指,加密方和解密方使用同样的秘钥来进行加密和解密。在对称加密算法中,数据发信方将明文(原始数据)和加密(密钥)一起经过特殊加密算法处理后,使其变成复杂的......
  • 常见的加密算法
    常见的加密算法目前常见的加密算法分类如下:1,单向散列加密算法  常见算法包括:MD5、sha1、sha256等2,对称加密算法  常见的算法有:DES、3DES、AES3,非对称加密算......
  • 量子图形加密算法的MATLAB代码实现
    一、概述目前主流的量子图形加密算法有量子像素编码算法(QuantumImagePixelEncoding,QIPE)、量子像素置乱算法(QuantumImagePixelScrambling,QIPS)等。一个简......
  • gitlab ssh无法clone(ssh-keygen加密算法问题)
    背景:gitlab比较古老的一个版本8.5.8(twang2218/gitlab-ce-zh:8.5.8).搭建方式可以参照:Kubernetes1.20.5安装gitlab。其实都是基于sameersbn的文档搭建的,甚是古老!开启了h......
  • Day 23 23.1:js加密算法
    js加密算法逆向重点掌握的内容:1.逆向的思维2.网站逆向的分析思路和步骤注意:重点不是放在代码中,而是分析的思路和套路(技巧)逆向到底是什么?通俗来讲,逆向就是处理爬虫过......
  • 加密,各种加密,耙梳加密算法(Encryption)种类以及开发场景中的运用(Python3.10)
    不用说火爆一时,全网热议的Web3.0区块链技术,也不必说诸如微信支付、支付宝支付等人们几乎每天都要使用的线上支付业务,单是一个简简单单的注册/登录功能,也和加密技术脱不了干......
  • nginx禁用3DES和DES弱加密算法,保证SSL证书安全 SSL/TLS协议信息泄露漏洞(CVE-2016-218
     cp-rnginx-1.19.2./nginx-1.19.2.bak查看完旧版本信息可以执行如下命令,给旧版本改个名mv./nginx./nginx.old漏洞名称SSL/TLS协议信息泄露漏洞(CVE-2016-2183)......