首页 > 其他分享 >OpenSSL 密码软件库学习

OpenSSL 密码软件库学习

时间:2023-10-07 23:55:27浏览次数:37  
标签:BIO string rsa RSA long OpenSSL char 密码 软件

说明:本次的密码算法采用C++编写,使用clion开发平台,Cmake编译配置工具;通过集成OpenSSL密码软件库,实现加解密功能。

1 对称加解密(AES)

1.1 AES简介:

   AES(Advanced Encryption Standard)是分组密码,每组的长度相同,为128位,即16个字节。密钥长度可以使用128位,192位或256位。密钥长度不同,加密轮数也不同。

AES的处理单位是字节,128位的明文分组P和密钥K都分为16个字节,其中P=(p0,```,p15),K=(k0,```,k15)。明文分组使用以节为单位的4*4矩阵描述,即状态矩阵;状态矩阵中字节排列顺序是从上到下,从左到右;每轮加密,状态矩阵发生变化,最终输出为密文。

   同样,128位密钥也使用方阵表示,矩阵的每一列称为1个32位比特字。通过密钥扩展,该密钥矩阵被排列成44个字组成的序列W=(W0,```,W43),其中W[0-3]为原始密钥,后面的密钥分成10组,每组的4个字作为轮密钥,用于10轮的加密。

                                             

              图1.1 明文矩阵                                                图1.2密钥矩阵

1.2 AES加解密规则:

          AES加密操作分为10轮,第1轮到第9轮加密的轮函数一样,包括4个操作:字节代换,行移位,列混淆和轮密钥加。第一轮开始时,先将原文和原密钥进行一次异或;最后一轮加密,不包括列混淆。AES解密过程与加密类似,每一轮的操作是加密操作的逆。

1.2.1字节代换

     AES中定义了一个S盒和逆S盒,即映射表,分别对应加密和解密。字节代换操作就是查表的过程,将状态矩阵中的元素按照一定规则映射成新的一个字节。即,将原有元素(16进制数)的高4位作为行,低4位作为列,选中行列相交的元素,然后替代原来的元素。例如,原来输出的元素Si是0x7f,将其拆分为0x7,0xf;选择0x7行,0xf列,挑选出相应的元素0x68。在新的状态表中,用0x68代替0x7f。

1.2.2 行移位

     行移位是对状态矩阵的每行进行相关的移位操作。加密过程,状态矩阵的第1行循环左移0位,第2行循环左移1位,第3行循环左移2位,第4行循环左移3位。解密过程,将状态矩阵的每行循环右移,位数与左移相同。

1.2.3 列混合

     列混合操作是通过矩阵的乘法来实现的,即S’=PS。其中P为固定的矩阵,S为变换前的矩阵,S’为变换后的矩阵。矩阵元素的乘法和加法都是定义在基于GF(2^8)上的二元运算。 列混合的逆操作,相当于将矩阵P变为P的逆。

1.2.4 密钥轮加

     将轮密钥W=(W[4i],W[4i+1],W[4i+2],W[4i+3])同状态矩阵S(S[0-3],S[4-7],s[8-11],s[12-15])进行异或操作。其中状态矩阵的每列可组成一个32位的字,与W[i]大小相同。

1.3 AES加解密的源代码(OpenSSL实现)

 1 #include <cstdio>
 2 #include <openssl/aes.h>
 3 #include <cstdlib>
 4 #include <cstring>
 5 
 6 #define AES_KEY_SIZE 128
 7 #define AES_BLOCK_SIZE 16
 8 #define N 3600
 9 
10 using namespace std;
11 
12 void aes_encrypt(unsigned char *plaintext, unsigned char *ciphertext, const unsigned char *key) {
13     AES_KEY aesKey;
14     AES_set_encrypt_key(key, AES_KEY_SIZE, &aesKey);
15     AES_encrypt(plaintext, ciphertext, &aesKey);
16 }
17 
18 void aes_decrypt(unsigned char *ciphertext, unsigned char *plaintext, const unsigned char *key) {
19     AES_KEY aesKey;
20     AES_set_decrypt_key(key, AES_KEY_SIZE, &aesKey);
21     AES_decrypt(ciphertext, plaintext, &aesKey);
22 }
23 
24 void inputPlain(char *&plainText, size_t &length) {
25     char str[N],ch;
26     length = 0;
27     while (true) {
28         ch = getchar();
29         if (ch == '\n') break;
30         str[length++] = ch;
31     }
32     str[length]='\0';
33     plainText=str;
34 }
35 
36 int main() {
37     char *plainText;
38     unsigned char *cipherText, *decryptedText;
39     size_t plainTextLen, cipherTextLen;
40     const unsigned char aesKey[] = {
41             0x7b, 0xf3, 0x5c, 0xd6, 0x9c, 0x47, 0x5d, 0x5e,
42             0x6f, 0x1d, 0x7a, 0x23, 0x18, 0x7b, 0xf9, 0x34
43     };
44 
45     //输入
46     printf("请输入明文(换行结束):\n");
47     fflush(stdout);
48     inputPlain(plainText, plainTextLen);
49 
50     //分配密文空间
51     cipherTextLen = (plainTextLen + AES_BLOCK_SIZE - 1) / AES_BLOCK_SIZE;
52     cipherTextLen *= AES_BLOCK_SIZE;
53     cipherText = new unsigned char[cipherTextLen];
54 
55     //对明文进行AES加密
56     aes_encrypt((unsigned char*)plainText, cipherText, aesKey);
57     *(cipherText+cipherTextLen)='\0';
58 
59     printf("加密后的密码:");
60     for (size_t i = 0; i < cipherTextLen; i++) {
61         printf("%02x", cipherText[i]);
62     }
63     printf("\n");
64 
65     decryptedText=new unsigned char[plainTextLen];
66 
67     aes_decrypt(cipherText,decryptedText,aesKey);
68 
69     printf("解密后的密码:%s\n",decryptedText);
70 
71     free(cipherText);
72     free(decryptedText);
73 
74     return 0;
75 }

  备注:代码参考 https://blog.csdn.net/buhuidage/article/details/129192727

2 非对称加密(RSA)

        RSA建立在大数分解的困难性之上。RSA 加密包括:密钥生成,加解密和签名验证。

2.1密钥生成

   (1)选择两个素数p和q,保密的。

 (2)计算整数n,n=p*q,公开的。

 (3)选择整数e,e与θ(n)互素(θ(n)=(p-1)(q-1)),1<e<θ(n),公开的。

 (4)计算d,d为e的乘法逆(modθ(n)),e*d=k*θ(n)+1

   则公钥pubKey={e,n},私钥priKey={d,p,q}

2.2 RSA算法的加解密

   RSA使用公钥加密,私钥解密。

   加密:C=Me mod n ,其中M为明文分组,C为密文分组,M<n。

   解密:M=Cd mod n = Med mod n = M(mod n)

 

   情景:收发双方都知道n,发方知道e,收方知道d。

       此时破解者Oscar,知道n,需要找到e,d,使得M=Med mod n。

2.3 RSA算法的签名模式

  RSA使用私钥签名,公钥验签
  签名:已有消息m,私钥(d,p,q),计算签名s。 ——s = md mod n
  验签:已有消息m,公钥(e,n),验证s是不是有效的签名。  ——验证:se = ? m mod n

2.4 RSA加解密源代码(OpenSSL实现)

  1 #include <stdio.h>
  2 #include <string>
  3 #include <openssl/rsa.h>
  4 #include <openssl/pem.h>
  5 #include <openssl/evp.h>
  6 
  7 using namespace std;
  8 
  9 
 10 /**
 11  * 生成密钥对,并保存为文件
 12  * @param pubFile
 13  * @param priFile
 14  * @param bits
 15  */
 16 void genKeyFile(const string &pubFile,const string &priFile,int bits){
 17     //生成公钥和私钥
 18     RSA *rsa= RSA_generate_key(bits,RSA_F4, nullptr, nullptr);
 19     BIO *bp= BIO_new(BIO_s_file());
 20     BIO_write_filename(bp,(void *) pubFile.c_str());
 21     PEM_write_bio_RSAPublicKey(bp,rsa);
 22     BIO_free_all(bp);
 23 
 24     bp=BIO_new(BIO_s_file());
 25     BIO_write_filename(bp,(void *) priFile.c_str());
 26     PEM_write_bio_RSAPrivateKey(bp,rsa,nullptr,nullptr,0,nullptr,nullptr);
 27     CRYPTO_cleanup_all_ex_data();
 28     BIO_free_all(bp);
 29     RSA_free(rsa);
 30 }
 31 
 32 //获取公钥和私钥
 33 void genKeyPair(string &pubKey,string &priKey,int bits){
 34     RSA *rsa= RSA_generate_key(bits,RSA_F4,nullptr,nullptr);
 35     BIO *kPub=BIO_new(BIO_s_mem());
 36     BIO *kPri=BIO_new(BIO_s_mem());
 37     int priKeyLen,pubKeyLen;
 38 
 39     PEM_write_bio_RSAPrivateKey(kPri,rsa,nullptr,nullptr,0,nullptr, nullptr);
 40     PEM_write_bio_RSA_PUBKEY(kPub,rsa);
 41 
 42     priKeyLen= BIO_pending(kPri);
 43     pubKeyLen= BIO_pending(kPub);
 44 
 45     priKey.resize(priKeyLen);
 46     pubKey.resize(pubKeyLen);
 47 
 48     BIO_read(kPri,priKey.c_str(),priKeyLen);
 49     BIO_read(kPub, pubKey.c_str(), pubKeyLen);
 50 
 51     RSA_free(rsa);
 52     BIO_free_all(kPri);
 53     BIO_free_all(kPub);
 54 }
 55 
 56 //读取公钥
 57 RSA* readPublicKey(const string &pubKey){
 58     BIO *bio= BIO_new_mem_buf(pubKey.data(),pubKey.length());
 59     RSA *rsa= PEM_read_bio_RSA_PUBKEY(bio,nullptr,nullptr,nullptr);
 60     BIO_free_all(bio);
 61     return rsa;
 62 }
 63 
 64 //读取私钥
 65 RSA* readPrivateKey(const string &priKey){
 66     BIO *bio= BIO_new_mem_buf(priKey.data(),priKey.length());
 67     RSA *rsa= PEM_read_bio_RSAPrivateKey(bio,nullptr, nullptr, nullptr);
 68     BIO_free_all(bio);
 69     return rsa;
 70 }
 71 
 72 
 73 /**
 74  * 公钥加密
 75  * @param in
 76  * @param out
 77  * @param pubKey
 78  */
 79 bool encrypt(const string &in,string &out,const string &pubKey){
 80     int keySize,inLen,readLen=0,len;
 81     const unsigned char *from;
 82     string to;
 83     RSA *rsa= readPublicKey(pubKey);
 84     if(rsa==nullptr)  return false;
 85 
 86     //分段加密
 87     keySize= RSA_size(rsa);
 88     inLen=in.length();
 89     from=(const unsigned char*)in.data();
 90     to.resize(keySize);
 91 
 92     do{
 93         len=(keySize-11)<inLen? (keySize-11):inLen;
 94         RSA_public_encrypt(len,(from+readLen),(unsigned char*)to.c_str(),rsa,RSA_PKCS1_PADDING);
 95         inLen-=len;
 96         readLen+=len;
 97         out.append(to);
 98     }while(inLen>0);
 99     RSA_free(rsa);
100 
101     return true;
102 }
103 
104 
105 /**
106  * 私钥解密
107  * @param in
108  * @param out
109  * @param priKey
110  */
111 bool decrypt(const string &in,string &out,const string &priKey){
112     unsigned char *from;
113     string to;
114     int keySize,inLen,readLen=0,len;
115     RSA *rsa= readPrivateKey(priKey);
116     if(rsa==nullptr)  return false;
117 
118     keySize= RSA_size(rsa);
119     from=(unsigned char*)in.data();
120     inLen=in.length();
121     to.resize(keySize);
122 
123     do{
124         len=RSA_private_decrypt(keySize,(from+readLen),(unsigned char*)to.c_str(),rsa,RSA_PKCS1_PADDING);
125         inLen-=keySize;
126         readLen+=keySize;
127         out.append(to.data(),len);
128     }while(inLen>0);
129     RSA_free(rsa);
130     return true;
131 }
132 
133 
134 /**
135  * 签名
136  * @param digest
137  * @param sign
138  * @param priKey
139  */
140 bool signa(const string &digest,string &sign,string &priKey){
141     string out;
142     unsigned int signLen=0;
143     RSA* rsa= readPrivateKey(priKey);
144     if(rsa==nullptr)  return false;
145     out.resize(RSA_size(rsa));
146 
147     RSA_sign(NID_sha1, (const unsigned char*)digest.c_str(), digest.length(),
148              (unsigned char*)out.c_str(), &signLen, rsa);
149 
150     sign.clear();
151     sign.append(out);
152     RSA_free(rsa);
153     return true;
154 }
155 
156 
157 /**
158  * 验签
159  * @param digest
160  * @param sign
161  * @param pubKey
162  */
163 bool verify(const string &digest,string &sign,string &pubKey){
164     RSA *rsa= readPublicKey(pubKey);
165     if(rsa== nullptr)
166         return false;
167 
168     int res=RSA_verify(NID_sha1,(const unsigned char*)digest.c_str(),digest.length(),
169                (const unsigned char*)sign.c_str(),sign.length(),rsa);
170     RSA_free(rsa);
171 
172     if(res==1)
173         return true;
174     return false;
175 }
176 
177 //准备数据
178 void prepareData(string &str,int size){
179     for(int i=0;i<size;i++){
180         str+=to_string((i%128));
181     }
182 }
183 
184 //哈希摘要
185 string hashDigests(string name,string data){
186     unsigned char mdValue[EVP_MAX_MD_SIZE]={0};
187     unsigned int mdLen=0;
188     const EVP_MD *md= nullptr;
189     string out;
190 
191     OpenSSL_add_all_digests();
192     md= EVP_get_digestbyname(name.c_str());
193     if(!md){
194         return NULL;
195     }
196 
197     EVP_MD_CTX *mdCtx=EVP_MD_CTX_new();
198     EVP_MD_CTX_init(mdCtx);
199     EVP_DigestInit_ex(mdCtx,md,nullptr);
200     EVP_DigestUpdate(mdCtx,data.data(),data.length());
201     EVP_DigestFinal_ex(mdCtx,mdValue,&mdLen);
202     EVP_MD_CTX_free(mdCtx);
203 
204     for(int i=0;mdValue[i]!=0;i++){
205         out+=mdValue[i];
206     }
207     return out;
208 }
209 
210 void testRSA(string data){
211     string priKey,pubKey;
212     string plainText=data,encryptedText,decryptedText;
213     string digest,sign;
214     int flag=1;
215 
216     genKeyFile("./pub.pem","./pri.pem",1024);
217     genKeyPair(pubKey, priKey, 1024);
218     if(!encrypt(plainText,encryptedText,pubKey)){
219         flag=0;
220         printf("RSA加密失败");
221     }
222     if(!decrypt(encryptedText,decryptedText,priKey)){
223         flag=0;
224         printf("RSA解密失败");
225     }
226     if(!flag)  return;
227 
228     if(decryptedText==plainText){
229         printf("加解密验证成功\n");
230     }
231 
232     digest=hashDigests("SHA256","i lost love");
233     signa(digest,sign,priKey);
234     bool res=verify(digest,sign,pubKey);
235     if(res){
236         printf("RSA 签名验证成功");
237     }
238     else{
239         printf("RSA签名验证失败");
240     }
241 }
242 
243 int main(){
244     string str;
245     prepareData(str,1024*512+9);
246     testRSA(str);
247 
248     return 0;
249 }

 备注:参考 https://blog.csdn.net/zyhse/article/details/113844114?

3 哈希计算

3.1 哈希函数的定义和特点

   哈希函数可将任意长度的消息压缩成固定长度的消息摘要。用于数字签名和消息鉴别码的构造。哈希函数表示为h=H(M)。

   哈希函数输入M为变长的消息,输出为定长的hash值h。

   单向性:从M计算h容易,从h计算M不可能。

   抗碰撞性>

    ①抗弱碰撞:对任何给定的消息x,找到满足y!=x且H(x)=H(y)的y,在计算上不可行。

    ②抗强碰撞:找到任何满足H(x)=H(y)的偶对(x,y)在计算上不可行。

   输入的微小变化,会引起输出的巨大变化。

3.2 MD5加密过程

  MD5以512位分组来处理输入的信息,且每一分组又被划分为16个子分组。算法的输出由4个32位分组组成,将这4个分组级联后生成一个128位散列值。

  (1)根据消息x构造M:M = x | 1 | 0…0 | Length。

    填充方法:信息的后面填充一个1和无数个0,满足其长度len mod512=448。接着在其后附加64位,表示填充前的长度。

         

 

                                      图3.1明文填充

   (2)哈希值计算

      ①设置链接变量A=67452301, B=efcdab89, C=98badcfe, D=10325476

      ②对每个消息分组做压缩计算

     

 

                                  图3.2 哈希计算过程

3.3 MD5摘要算法源码(OpenSSL实现)

 1 #include <cstdio>
 2 #include <string>
 3 #include <openssl/evp.h>
 4 
 5 using namespace std;
 6 //准备数据
 7 void prepareData(string &str,int size){
 8     for(int i=0;i<size;i++){
 9         str+=to_string((i%128));
10     }
11 }
12 //摘要算法
13 string hashDigests(string name,string data){
14     unsigned char mdValue[EVP_MAX_MD_SIZE]={0};
15     unsigned int mdLen=0;
16     const EVP_MD *md= nullptr;
17     string out;
18 
19     OpenSSL_add_all_digests();
20     md= EVP_get_digestbyname(name.c_str());
21     if(!md){
22         return NULL;
23     }
24 
25     EVP_MD_CTX *mdCtx=EVP_MD_CTX_new();
26     EVP_MD_CTX_init(mdCtx);
27     EVP_DigestInit_ex(mdCtx,md,nullptr);
28     EVP_DigestUpdate(mdCtx,data.data(),data.length());
29     EVP_DigestFinal_ex(mdCtx,mdValue,&mdLen);
30     EVP_MD_CTX_free(mdCtx);
31 
32     for(int i=0;mdValue[i]!=0;i++){
33         out+=mdValue[i];
34     }
35     return out;
36 }
37 
38 int main(){
39     string str;
40     prepareData(str,1*1024*1024+7);
41 
42     string sha256=hashDigests("SHA256",str);
43     string sha1=hashDigests("SHA1",str);
44     string md5=hashDigests("MD5",str);
45 
46     char *chSha256=(char*)sha1.c_str();
47     char *chSha1=(char*)sha256.c_str();
48     char *chMd5=(char*)md5.c_str();
49 
50     for(int i=0;chSha1[i]!='\0';i++){
51         printf("%x",chSha1[i]);
52     }
53     printf("\n");
54 
55     for(int i=0;chSha256[i]!='\0';i++){
56         printf("%x",chSha256[i]);
57     }
58     printf("\n");
59 
60     for(int i=0;chMd5[i]!='\0';i++){
61         printf("%x",chMd5[i]);
62     }
63     printf("\n");
64 
65     return 0;
66 }

 备注:参考 https://blog.csdn.net/zyhse/article/details/113844114?

4  C++模拟RSA加解密

   使用vs2022编写 程序模拟RSA的加解密。

(1)RSA.h

 1 #pragma once  
 2     #include <cstdio>  
 3     #include <iostream>  
 4     #include <stdlib.h>  
 5     #include <cstring>  
 6     #define N 1024  
 7       
 8     class RSA {  
 9         int p, q, len;  
10         long n, r, e, d;  
11         long long* pText, * cText, * dText;  
12     public:  
13         void init();  
14         RSA();  
15         bool isPrime(long);  
16         long gcd(long, long);  
17         void inputPQ();  
18         void genKeyPair();  
19             long quickPower(long long, long, long);  
20         char* encrypt(char*);  
21         char* decrypt();  
22     };

(2)RSA.cpp

1.    #include "RSA.h"  
2.      
3.    using namespace std;  
4.    string res = "\0";  
5.    char ds[N] = { 0 };  
6.      
7.    void  mLtoa(long long num, char* str, int radix)  
8.    {  
9.        int i = 0;  
10.        int j = 0;  
11.        long long sum;  
12.        unsigned long long num1 = num;  //如果是负数求补码,必须将他的绝对值放在无符号位中在进行求反码  
13.        char str1[33] = { 0 };  
14.        if (num < 0) {              //求出负数的补码  
15.            num = -num;  
16.            num1 = ~num;  
17.            num1 += 1;  
18.        }  
19.        if (num == 0) {  
20.            str1[i] = '0';  
21.      
22.            i++;  
23.        }  
24.        while (num1 != 0) {                      //进行进制运算  
25.            sum = num1 % radix;  
26.            str1[i] = (sum > 9) ? (char)((sum - 10) + 'a') : (char)(sum + '0');  
27.            num1 = num1 / radix;  
28.            i++;  
29.        }  
30.        i--;  
31.      
32.        for (i; i >= 0; i--) {               //逆序输出   
33.            str[i] = str1[j];  
34.            j++;  
35.        }  
36.      
37.    }  
38.      
39.    void RSA::init() {  
40.        this->p = 0;  
41.        this->q = 0;  
42.        this->n = 0;  
43.        this->d = 0;  
44.        this->e = 0;  
45.        this->r = 0;  
46.        this->len = 0;  
47.        cText = new long long[N];  
48.        pText = new long long[N];  
49.        dText = new long long[N];  
50.    }  
51.      
52.    RSA::RSA() {  
53.        init();  
54.    }  
55.      
56.    bool RSA::isPrime(long t) {  
57.        if (t == 1) return false;  
58.        for (int i = 2; i <= t / i; i++) {  
59.            if (t % i == 0) {  
60.                return false;  
61.            }  
62.        }  
63.        return true;  
64.    }  
65.      
66.    long RSA::gcd(long a, long b) {  
67.        return b == 0 ? a : gcd(b, a % b);  
68.    }  
69.      
70.    void RSA::inputPQ() {  
71.        int p, q;  
72.        while (1) {  
73.            printf("请输入两个大于200的素数(p,q):");  
74.            cin >> p >> q;  
75.      
76.            if (p <= 200 || q <= 200) {  
77.                printf("输入的素数太小,请重新输入\n");  
78.                continue;  
79.            }  
80.            if (!isPrime(p)) {  
81.                printf("p不是素数,请重新输入!\n");  
82.                continue;  
83.            }  
84.            if (!isPrime(q)) {  
85.                printf("q不是素数,请重新输入!\n");  
86.                continue;  
87.            }  
88.      
89.            this->p = p;  
90.            this->q = q;  
91.            this->n = p * q;  
92.            this->r = (p - 1) * (q - 1);  
93.            break;  
94.        }  
95.    }  
96.      
97.    void RSA::genKeyPair() {  
98.        long value = 1;  
99.        inputPQ();  
100.      
101.        for (int i = 2; i < r; i++) {  
102.            if (gcd(r, i) == 1) {  
103.                this->e = i;  
104.                break;  
105.            }  
106.        }  
107.      
108.        for (long j = 1;; j++) {  
109.            value = j * this->r + 1;  
110.            if (value % this->e == 0 && value / this->e < this->r) {  
111.                this->d = value / this->e;  
112.                break;  
113.            }  
114.        }  
115.      
116.        printf("设定的公钥为(%ld,%ld)\n", this->e, this->n);  
117.        printf("生成的私钥为(%ld,%d,%d)\n", this->d, this->p, this->q);  
118.    }  
119.      
120.    long RSA::quickPower(long long a, long b, long n) {  
121.        long res = 1;  
122.        while (b > 0) {  
123.            if ((b & 1) != 0)  
124.                res = (res * a) % n;  
125.            b = b >> 1;  
126.            a = (a * a) % n;  
127.        }  
128.        return res;  
129.    }  
130.      
131.    char* RSA::encrypt(char* str) {  
132.        unsigned char ch;  
133.        char* es, cipher[N];  
134.      
135.        for (int i = 0; str[i] != 0; i++) {  
136.            if (i > N) {  
137.                realloc(cText, N * ((i / 1024) + 1) * sizeof(int64_t));  
138.                realloc(pText, N * ((i / 1024) + 1) * sizeof(int64_t));  
139.                realloc(dText, N * ((i / 1024) + 1) * sizeof(int64_t));  
140.            }  
141.      
142.            ch = (unsigned char)str[i];  
143.            pText[i] = ch;  
144.            cText[i] = quickPower(pText[i], this->e, this->n);  
145.            memset(cipher, 0, sizeof(cipher));  
146.            mLtoa(cText[i], cipher, 16);  
147.            res.append(cipher);  
148.            this->len++;  
149.        }  
150.        es = (char*)res.c_str();  
151.      
152.        return es;  
153.    }  
154.      
155.    char* RSA::decrypt() {  
156.        for (int i = 0; i < len; i++) {  
157.            dText[i] = quickPower(cText[i], this->d, this->n);  
158.            ds[i] = (char)dText[i];  
159.        }  
160.        return ds;  
161.    } 
(3)demo.cpp
1.    #include "RSA.h"  
2.      
3.    using namespace std;  
4.    char* cipherText, * decryptedText;  
5.    char plainText[N], ch;  
6.    int len = 0;  
7.    RSA rsa;  
8.      
9.    int main() {  
10.      
11.        memset(plainText, 0, sizeof(plainText));  
12.      
13.        printf("请输入待加密的明文(以换行结束):\n");  
14.        while (true) {  
15.            ch = getchar();  
16.            if (ch == '\n') break;  
17.            plainText[len++] = ch;  
18.        }  
19.        fflush(stdout);  
20.      
21.        rsa.genKeyPair();  
22.      
23.        cipherText = rsa.encrypt(plainText);  
24.        decryptedText = rsa.decrypt();  
25.      
26.        printf("加密密文:");  
27.        printf("%s\n", cipherText);  
28.      
29.        printf("解密原文:");  
30.        printf("%s\n", decryptedText);  
31.      
32.        return 0;  
33.    } 

 

 

标签:BIO,string,rsa,RSA,long,OpenSSL,char,密码,软件
From: https://www.cnblogs.com/tunerforsea/p/by.html

相关文章

  • 软件设计师学习-海明码
    wiki海明码(HammingCode)是由贝尔实验室的RichardHamming设计的,是一种利用奇偶校验来检错和纠错的校验方法。方法是在数据位插入k个校验位,通过扩大码距来实现检错和纠错。1.理论构成设数据位有n位置,校验位有k位,则n与k需要满足关系:2k-1≥n+k。按照如下规则......
  • 谷歌记住密码,设置浏览器 免登录
      """"读chrome本地cookie数据(需要先手动登录勾选记住密码),实现免登陆操作注意:关闭chrome浏览器,否则运行报错!!!"""fromtimeimportsleepfromseleniumimportwebdriverfromselenium.webdriver.chrome.optionsimportOptionsdefget_cookie(url):#实例......
  • 软件测评怎么做?首选第三方软件检测机构
    ​ 第三方软件测评机构1.明确测试需求,形成清晰可量化的测试项如甲方信息化建设项目验收测试,一般参考合同签订的内容要求、开发阶段甲方提出的需求更改以及增加需求、最终需要做验收测试报告时与甲方再次核实参考监理单位意见来敲定测试内容。如,政府科技项目验收测试则依照科......
  • Gitlab管理员忘记密码
    目录Gitlab管理员忘记密码一、背景二、邮箱方式找回1.在gitlab登录窗口2.输入邮箱账号找回3.重设密码三、Bash命令方式找回1.切换到git用户2.查看gitlab命令文件3.进入gitlab控制台4.查询gitlab超级管理员信息4.重置密码并报存用户对象5.返回gitlab登录界面重新登录Gitlab管理员......
  • LookHandles.exe软件多开窗口修改标题
    当我们针对某个软件进行多开以后,比如我们多开了电脑版微信。此时,使用UI自动化工具是无法准确确定窗口的,因为窗口的名称和类名都一样我们可以使用LookHandles.exe修改窗口名称修改窗口名称LookHandles.exe使用方法LookHandles.exe点住放大镜,移动到想要修改的窗口上,比如微信窗......
  • 如何开发量化交易软件
    量化交易软件是利用程序来实现交易决策的方式软件,它能帮助交易者实现短期内的大量交易,通过觉得和优化实现高效率的盈利,下面就是关于开发量化策略的一些软件需求建议。1.确定交易目标和策略先明确好量化的目标策略,交易目标,盈利点,控制风险,资产配置,交易策略。按照市场的指定规则来交......
  • 量化交易软件开发
    量化交易软件是利用一种数据模型进行交易的方式,通过计算机程序实现自动的交易,量化交易软件实现这一目标是关键词工具,开发和维护也是成为交易领域的重要途径。在开发量化交易软件时,开发人员需要考虑多种的因素,例如市场的数据,交易模型,风险控制,策略优化等。还需要各种的编程语言,构建......
  • 量化交易系统软件是怎么赚钱的
    量化交易系统软件的原理是通过复杂的算法和统计模型计算进行交易的,利用软件赚钱利润。这些软件能快速的分析出大量的数据,包括历史数据,往期数据,其他数据等,软件是发现隐藏在市场趋势的盈利点,预测未来的价格波动变化点。量化交易软件是利用高速计算的算法,在毫秒之间分析得出决策,比人......
  • 水母量化交易系统软件
    水母量化交易系统软件是一款针对交易员而开发的,它具有交易轻松,简单,功能强大,稳定性好的特点。帮助投资者更好的实现管理,实现利益最大化。水母量化交易系统软件的主要功能包括:1.水母交易策略编辑器:交易员自定义软件策略,包括均线,曲线,硬性指标,周边的交易信号等。2.风险控制:软件自动......
  • LookHandles.exe软件多开窗口修改标题
    当我们针对某个软件进行多开以后,比如我们多开了电脑版微信。此时,使用UI自动化工具是无法准确确定窗口的,因为窗口的名称和类名都一样我们可以使用LookHandles.exe修改窗口名称修改窗口名称LookHandles.exe使用方法LookHandles.exe点住放大镜,移动到想要修改的窗口上,比如微信窗口,然......