当前位置:   article > 正文

简单阐述对称加密算法和非对称加密算法(附C++示例代码,以openssl实现AES、DES、RSA、ECC、DSA算法加密)_对称密文检索和非对称密文检索的例子

对称密文检索和非对称密文检索的例子

        对称加密和非对称加密是两种常见的加密方法。常见的对称加密算法:AES、DES等,常见的非对称加密算法有RSA、DSA、ECC等。本篇简单介绍这些算法并做对比。

目录

一. 对称加密

1.1 介绍及代码实例

1.2 对称加密使用场景

1.3 对称加密需要注意的

1.4 常见的对称加密算法

1.4.1 AES     

1.4.2 DES

1.4.3 3DES 

1.4.4 其他对称加密算法

二. 非对称加密

2.1 介绍及代码实例

2.2 非对称加密使用场景

2.3 非对称加密需要注意的

2.4 常见的非对称加密算法

2.4.1 RSA       

2.4.2 ECC

2.4.3 DSA

2.4.4 其他非对称加密算法

三. 总结


一. 对称加密

1.1 介绍及代码实例

        对称加密是一种加密方式,其中使用单个密钥来加密和解密数据。这意味着,如果您使用对称加密来加密消息,则必须使用相同的密钥来解密消息。对称加密的优点在于它非常快,因为它仅需要使用单个密钥。然而,对称加密的缺点在于,必须安全地分发密钥,否则任何人都可以访问加密的信息。

        以使用openssl库中的对称加密为例:

  1. #include <openssl/evp.h>
  2. #include <string.h>
  3. int main() {
  4. // 初始化加密库
  5. OpenSSL_add_all_algorithms();
  6. // 创建一个加密上下文
  7. EVP_CIPHER_CTX *ctx;
  8. ctx = EVP_CIPHER_CTX_new();
  9. // 设置加密算法
  10. const EVP_CIPHER *cipher = EVP_aes_256_cbc();
  11. // 设置加密密钥和初始化向量
  12. unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
  13. memset(key, 0, EVP_MAX_KEY_LENGTH);
  14. memset(iv, 0, EVP_MAX_IV_LENGTH);
  15. // 初始化加密上下文
  16. EVP_EncryptInit_ex(ctx, cipher, NULL, key, iv);
  17. // 准备待加密的明文
  18. unsigned char plaintext[] = "Hello, world!";
  19. int plaintext_len = strlen((char *)plaintext);
  20. // 分配空间存储密文
  21. unsigned char ciphertext[plaintext_len + EVP_MAX_BLOCK_LENGTH];
  22. int ciphertext_len;
  23. // 加密明文
  24. EVP_EncryptUpdate(ctx, ciphertext, &ciphertext_len, plaintext, plaintext_len);
  25. // 完成加密过程
  26. EVP_EncryptFinal_ex(ctx, ciphertext + ciphertext_len, &ciphertext_len);
  27. // 释放加密上下文
  28. EVP_CIPHER_CTX_free(ctx);
  29. // 处理密文
  30. // ...
  31. return 0;
  32. }

1.2 对称加密使用场景

        对称加密的使用场景:

对称加密是一种常用的加密方法,它的使用场景很广泛。一般来说,对称加密可以用来保护数据的机密性、完整性和可靠性。下面列举几种常见的使用场景:

  1. 信息加密:对称加密可以用来加密文本、音频、视频等数据,以保护数据的机密性。

  2. 通信加密:在通信过程中,对称加密可以用来保护通信内容的机密性,例如在网络通信中使用对称加密来保护数据包的内容。

  3. 文件加密:对称加密可以用来加密文件,以保护文件的机密性。

  4. 数据库加密:对称加密可以用来加密数据库中的数据,以保护数据库中的数据不被窃取。

  5. 密码存储:对称加密可以用来加密用户密码,以保护用户密码的安全。

  6. 身份认证:对称加密可以用来进行身份认证,例如通过对称加密的方式实现双向身份认证。

  7. 电子商务:在电子商务中,对称加密可以用来保护交易信息的机密性。

                                                                                                                           来自ChatGPT

1.3 对称加密需要注意的

        对称加密是一种常用的加密方法,它使用相同的密钥来加密和解密信息。对于对称加密,有几点需要注意:

  1. 密钥管理:对称加密使用相同的密钥来加密和解密信息,因此密钥的安全管理是非常重要的。密钥应该被安全地存储,并且在使用时应该保持机密性。

  2. 密钥长度:对称加密的安全性取决于密钥的长度。通常来说,密钥越长,对称加密越安全。但是,密钥过长可能会导致加密和解密的性能下降。

  3. 算法的安全性:对称加密使用各种算法来实现加密和解密。某些算法可能被破解,因此在使用对称加密时应该选择安全性较高的算法。

  4. 加密后数据的安全性:加密后的数据仍然可能遭到破坏。例如,如果加密后的数据被截获,可能会对数据安全造成威胁。因此,在使用对称加密时,应该采取适当的措施来确保加密后的数据的安全性。

1.4 常见的对称加密算法

 常见的对称加密算法包括:

  • AES (Advanced Encryption Standard)
  • DES (Data Encryption Standard)
  • 3DES (Triple DES)
  • Blowfish
  • Twofish

1.4.1 AES     

        AES(Advanced Encryption Standard)的加密过程分为若干轮,每一轮都使用一个 4x4 的矩阵(称为轮密钥)对输入数据进行变换。在每一轮中,输入数据会经过如下几个步骤:

  1. 字节代换(Byte Substitution):将输入数据中的每一个字节替换成一个固定的字节。

  2. 行移位(Shift Row):将输入数据的每一行向左移动一定的位数。

  3. 列混淆(Mix Column):将输入数据的每一列与一个固定的矩阵相乘。

  4. 轮密钥加(Round Key Addition):将输入数据与当前轮的轮密钥相加。

        在进行多轮加密之后,输入数据就被转换成了加密后的密文。解密时,只需要使用相同的密钥,并按照相反的顺序执行上述步骤即可将密文转换回原来的明文。

        AES 的密钥长度可以是 128 位、192 位或 256 位。

        下面是一个使用 C++ 实现 AES 加密和解密的简单代码示例:

  1. #include <iostream>
  2. #include <string>
  3. #include <openssl/aes.h>
  4. using namespace std;
  5. int main()
  6. {
  7. // 要加密的明文
  8. string plaintext = "This is the message to be encrypted.";
  9. // 密钥,必须是 16、24 或 32 字节的长度
  10. unsigned char key[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  11. 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
  12. // 初始向量,必须是 16 字节的长度
  13. unsigned char iv[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  14. 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
  15. // 加密
  16. int length = plaintext.size();
  17. int ciphertext_len = 0;
  18. unsigned char ciphertext[length];
  19. AES_KEY enc_key;
  20. AES_set_encrypt_key(key, 128, &enc_key);
  21. AES_cbc_encrypt((unsigned char *)plaintext.c_str(), ciphertext, length, &enc_key, iv, AES_ENCRYPT);
  22. ciphertext_len = length;
  23. cout << "Ciphertext: " << ciphertext << endl;
  24. // 解密
  25. int decryptedtext_len = 0;
  26. unsigned char decryptedtext[length];
  27. AES_KEY dec_key;
  28. AES_set_decrypt_key(key, 128, &dec_key);
  29. AES_cbc_encrypt(ciphertext, decryptedtext, ciphertext_len, &dec_key, iv, AES_DECRYPT);
  30. decryptedtext_len = ciphertext_len;
  31. decryptedtext[decryptedtext_len] = '\0';
  32. cout << "Decrypted text: " << decryptedtext << endl;
  33. return 0;
  34. }

1.4.2 DES

        DES (Data Encryption Standard)算法基于分组密码,即将明文分成固定长度的块,然后对每个块进行加密。DES 算法使用 56 位密钥和 64 位明文块,并采用 16 轮的加密过程。在每轮中,DES 算法使用密钥对明文块进行变换,以生成密文块。

        DES 算法被广泛应用,但随着计算机的发展,人们开始发现 DES 算法的密钥长度较短,可能被暴力破解。因此,许多组织和个人已经放弃使用 DES 算法,转而使用更强的加密算法,如 AES (Advanced Encryption Standard)。

        简短示例代码,TODO部分自行寻找,定义为函数即可。

  1. #include <iostream>
  2. #include <string>
  3. using namespace std;
  4. const int BLOCK_SIZE = 8; // DES 加密块的大小为 8 字节
  5. // 将字符串转换为 8 字节的二进制块
  6. void str_to_block(string str, int block[]) {
  7. // 如果字符串的长度不足 8 字节,则在末尾补 0
  8. int len = str.length();
  9. for (int i = 0; i < BLOCK_SIZE; i++) {
  10. if (i < len) {
  11. block[i] = (int)str[i];
  12. } else {
  13. block[i] = 0;
  14. }
  15. }
  16. }
  17. // 将 8 字节的二进制块转换为字符串
  18. string block_to_str(int block[]) {
  19. string str;
  20. for (int i = 0; i < BLOCK_SIZE; i++) {
  21. str += (char)block[i];
  22. }
  23. return str;
  24. }
  25. // 打印 8 字节的二进制块
  26. void print_block(int block[]) {
  27. for (int i = 0; i < BLOCK_SIZE; i++) {
  28. cout << block[i] << " ";
  29. }
  30. cout << endl;
  31. }
  32. int main() {
  33. // 待加密的字符串
  34. string plaintext = "Hello DES";
  35. // 将字符串转换为 8 字节的二进制块
  36. int block[BLOCK_SIZE];
  37. str_to_block(plaintext, block);
  38. // 打印原始块
  39. cout << "原始块:" << endl;
  40. print_block(block);
  41. // TODO: 进行 DES 加密
  42. // 打印加密后的块
  43. cout << "加密后的块:" << endl;
  44. print_block(block);
  45. // 将加密后的块转换为字符串
  46. string ciphertext = block_to_str(block);
  47. cout << "加密后的字符串:" << ciphertext << endl;
  48. return 0;
  49. }

1.4.3 3DES 

        3DES(Triple DES)是一种对称加密算法,也称为三重数据加密标准。它是DES加密算法的改进版,在DES的基础上加入了一层加密,提高了安全性。

        3DES加密过程是这样的:首先,使用第一个密钥对明文进行加密;然后,将加密后的密文再使用第二个密钥进行解密;最后,将解密后的结果再使用第三个密钥进行加密。这样一来,就形成了三重加密的过程,也就是3DES的名字由来。

        3DES使用三个56位的密钥进行加密,其密钥长度是168位。它的安全性比DES高,但是比较复杂,计算速度慢。目前,3DES仍被广泛使用,尤其是在金融行业。

        这段代码使用了 OpenSSL 库中的函数来实现 3DES 加密,需要在编译时添加 -lcrypto 参数:

  1. #include <iostream>
  2. #include <openssl/des.h>
  3. #include <cstring>
  4. using namespace std;
  5. int main()
  6. {
  7. // 定义加密用的三个密钥
  8. unsigned char key1[8] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
  9. unsigned char key2[8] = {0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01};
  10. unsigned char key3[8] = {0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23};
  11. // 定义需要加密的明文
  12. unsigned char plain[8] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
  13. // 定义加密后的密文
  14. unsigned char cipher[8];
  15. // 定义 DES_key_schedule 结构体,用于存储密钥信息
  16. DES_key_schedule ks1, ks2, ks3;
  17. // 使用三个密钥分别设置三个 DES_key_schedule 结构体
  18. DES_set_key_unchecked((const_DES_cblock*)key1, &ks1);
  19. DES_set_key_unchecked((const_DES_cblock*)key2, &ks2);
  20. DES_set_key_unchecked((const_DES_cblock*)key3, &ks3);
  21. // 使用三个密钥和三个 DES_key_schedule 结构体加密明文
  22. DES_ecb3_encrypt((const_DES_cblock*)plain, (DES_cblock*)cipher, &ks1, &ks2, &ks3, DES_ENCRYPT);
  23. // 输出密文
  24. for (int i = 0; i < 8; i++)
  25. {
  26. cout << hex << (int)cipher[i] << " ";
  27. }
  28. cout << endl;
  29. return 0;
  30. }

1.4.4 其他对称加密算法

        Blowfish是一种对称加密算法,由Bruce Schneier在1993年发明。它是一种快速、安全的密码算法,并且具有可扩展性和灵活性。Blowfish算法使用一个可变长度的密钥来加密和解密数据。密钥的长度可以在4至56个字节之间变化,但通常为16或24个字节。它采用64位分组加密,并使用Feistel结构,其中包含18轮迭代。Blowfish算法的安全性得到了广泛的认可,并被许多软件包括在内,例如OpenSSH和GnuPG。它也被许多商业公司用作加密解决方案。

        Twofish是之前Blowfish算法加密算法,它曾是NIST替换DES算法的高级加密标准(AES)算法的候选算法。(NIST最终选择了Rijndael算法)

二. 非对称加密

2.1 介绍及代码实例

        非对称加密是另一种加密方式,其中使用两个不同的密钥来加密和解密数据。这两个密钥是一对,其中一个密钥用于加密(叫做公钥),另一个密钥用于解密(叫做私钥)。由于公钥和私钥是不同的,因此只有拥有私钥的人才能解密使用公钥加密的信息。非对称加密的优点在于,您可以公开公钥,而不用担心安全性,因为只有拥有私钥的人才能解密信息。但是,非对称加密通常比对称加密慢得多,因此在对安全性要求不高的情况下,对称加密通常是更好的选择

  1. #include <iostream>
  2. #include <string>
  3. #include <cryptopp/rsa.h>
  4. #include <cryptopp/osrng.h>
  5. #include <cryptopp/base64.h>
  6. #include <cryptopp/files.h>
  7. using namespace std;
  8. using namespace CryptoPP;
  9. int main()
  10. {
  11. // 生成密钥对
  12. AutoSeededRandomPool rng;
  13. RSA::PrivateKey privateKey;
  14. privateKey.GenerateRandomWithKeySize(rng, 2048);
  15. RSA::PublicKey publicKey(privateKey);
  16. // 保存密钥对到文件
  17. string privFilename = "private.key";
  18. string pubFilename = "public.key";
  19. SavePrivateKey(privateKey, privFilename.c_str());
  20. SavePublicKey(publicKey, pubFilename.c_str());
  21. // 从文件加载密钥对
  22. RSA::PrivateKey loadedPrivateKey;
  23. RSA::PublicKey loadedPublicKey;
  24. LoadPrivateKey(loadedPrivateKey, privFilename.c_str());
  25. LoadPublicKey(loadedPublicKey, pubFilename.c_str());
  26. // 加密
  27. string message = "Hello, World!";
  28. string encrypted;
  29. StringSource(message, true,
  30. new PK_EncryptorFilter(rng, loadedPublicKey,
  31. new StringSink(encrypted)
  32. )
  33. );
  34. // 解密
  35. string decrypted;
  36. StringSource(encrypted, true,
  37. new PK_DecryptorFilter(rng, loadedPrivateKey,
  38. new StringSink(decrypted)
  39. )
  40. );
  41. // 输出结果
  42. cout << "Original message: " << message << endl;
  43. cout << "Encrypted message: " << encrypted << endl;
  44. cout << "Decrypted message: " << decrypted << endl;
  45. return 0;
  46. }

2.2 非对称加密使用场景

        下面列举了一些非对称加密的常见使用场景:

  1. 网络安全:非对称加密常用于保护数据在网络上传输的安全性,例如使用 HTTPS 协议的网站就通常使用非对称加密来保护数据的安全。

  2. 身份认证:非对称加密也可以用于身份认证,例如在网络上登录时,用户的身份信息可以使用非对称加密来保护。

  3. 电子签名:非对称加密也可以用于创建电子签名,用于对数字文档进行签名,以保证文档的真实性和完整性。

  4. 加密文件:非对称加密也可以用于加密文件,以保护文件的保密性。

  5. 密钥交换:非对称加密还可以用于密钥交换,例如在两个用户之间交换密钥时,可以使用非对称加密来保护。

2.3 非对称加密需要注意的

        使用非对称加密时,需要注意以下几点:

  1. 公钥和私钥必须保存在安全的地方,并且只能由它们的所有者访问。否则,其他人可能会获得私钥并使用它来解密数据。

  2. 公钥和私钥的生成和管理应由可信任的机构或个人进行。这样可以确保密钥的安全性和有效性。

  3. 密钥的长度越长,加密的安全性就越高。因此,使用较长的密钥可以提高加密的安全性。

  4. 使用不同的密码学算法可以提高加密的安全性。目前比较流行的算法包括RSA、Elliptic Curve Cryptography (ECC)和Diffie-Hellman。

  5. 在使用非对称加密进行通信时,应避免重复使用密钥。这样可以防止密钥被暴力破解。

  6. 应定期更换密钥以保持安全性。这样可以防止密钥被黑客攻击或遗忘。

2.4 常见的非对称加密算法

        常用的非对称加密算法包括:

  1. RSA:最常用的非对称加密算法,由美国国家安全局(NSA)在1977年发明。RSA使用一对公钥和私钥来加密和解密数据。

  2. ECC(椭圆曲线加密算法):一种高效的非对称加密算法,常用于加密较小的数据块,如数字签名和加密聊天消息。

  3. DSA(数字签名算法):一种常用的数字签名算法,用于生成和验证数字签名。

  4. DH(Diffie-Hellman):一种常用的密钥交换算法,可用于在两个计算机之间安全地交换密钥。

  5. ElGamal:一种可用于加密和数字签名的非对称加密算法。

  6. PGP(Pretty Good Privacy):一种常用的电子邮件加密软件,使用多种非对称加密算法来保护电子邮件的隐私。

        在选择非对称加密算法时,应考虑算法的安全性、性能和适用的应用场景。一般来说,RSA和ECC是最常用的非对称加密算法。

2.4.1 RSA       

        RSA是一种常见的非对称加密算法。它是由Ron Rivest, Adi Shamir, and Leonard Adleman三位科学家在1977年发明的。

        在RSA加密算法中,有两个关键的概念:公钥和私钥。公钥是可以被任何人获取的,而私钥则是保存在拥有者自己的计算机上的。

        当使用RSA加密时,加密过程如下:

  1. 发送方将明文(要加密的信息)使用接收方的公钥进行加密。

  2. 加密后的密文(已加密的信息)被发送给接收方。

  3. 接收方使用自己的私钥解密密文,从而获得明文。

        由于RSA加密使用的是非对称加密,因此发送方使用接收方的公钥加密信息,而接收方则使用自己的私钥解密信息。这种方式可以确保通信过程中信息的安全。

        RSA加密算法通常用于在不安全的网络中传输敏感信息,如在互联网上进行金融交易时。它也常用于数字签名的场景,以确保信息的完整性和真实性。

        代码示例:

  1. #include <iostream>
  2. #include <string>
  3. #include <openssl/rsa.h>
  4. #include <openssl/pem.h>
  5. int main()
  6. {
  7. // Generate the RSA key pair
  8. RSA* keypair = RSA_generate_key(2048, RSA_F4, NULL, NULL);
  9. // Extract the public key from the key pair
  10. const BIGNUM* n = keypair->n;
  11. const BIGNUM* e = keypair->e;
  12. RSA* pubkey = RSA_new();
  13. RSA_set0_key(pubkey, BN_dup(n), BN_dup(e), NULL);
  14. // Get the message to be encrypted
  15. std::string message = "Hello, world!";
  16. // Allocate memory for the encrypted message
  17. unsigned char* encrypted_message = new unsigned char[RSA_size(pubkey)];
  18. // Encrypt the message
  19. int result = RSA_public_encrypt(message.size(), (const unsigned char*) message.c_str(), encrypted_message, pubkey, RSA_PKCS1_OAEP_PADDING);
  20. if (result == -1)
  21. {
  22. // Error occurred during encryption
  23. std::cerr << "Error: RSA encryption failed" << std::endl;
  24. return 1;
  25. }
  26. // Print the encrypted message
  27. std::cout << "Encrypted message: ";
  28. for (int i = 0; i < result; i++)
  29. std::cout << std::hex << (encrypted_message[i] & 0xff) << " ";
  30. std::cout << std::endl;
  31. // Clean up
  32. RSA_free(keypair);
  33. RSA_free(pubkey);
  34. delete[] encrypted_message;
  35. return 0;
  36. }

2.4.2 ECC

        ECC(椭圆曲线密码)是一种公钥密码体制,它使用椭圆曲线来生成密钥对和进行加密和解密。它的优点在于,相比于其他密码算法,ECC在保证相同的安全级别的情况下,所需的密钥更短,因此可以更有效地使用带宽和计算资源。

        ECC的工作原理如下:

  1. 首先,选择一个椭圆曲线和一个点作为基点。

  2. 生成一对密钥:公钥和私钥。公钥是一个椭圆曲线上的点,私钥是一个整数。

  3. 加密过程:假设有一个发送者(Alice)想要向一个接收者(Bob)发送一条信息。Alice使用Bob的公钥和自己的私钥对信息进行加密,然后将加密后的信息发送给Bob。

  4. 解密过程:Bob收到加密信息后,使用自己的私钥和Alice的公钥对信息进行解密。

        ECC的安全性依赖于找到私钥所需的时间。在ECC中,破解私钥的时间与私钥长度成正比,因此使用ECC的密钥可以比使用其他密码算法的密钥短得多,同时仍然具有相同的安全级别。

  1. #include <iostream>
  2. #include <string>
  3. #include <openssl/ec.h>
  4. #include <openssl/evp.h>
  5. #include <openssl/pem.h>
  6. int main() {
  7. // 生成密钥对
  8. EC_KEY *key = EC_KEY_new_by_curve_name(NID_secp256k1);
  9. EC_KEY_generate_key(key);
  10. // 将公钥写入文件
  11. BIO *bio = BIO_new_file("public.pem", "w");
  12. PEM_write_bio_EC_PUBKEY(bio, key);
  13. BIO_free(bio);
  14. // 将私钥写入文件
  15. bio = BIO_new_file("private.pem", "w");
  16. PEM_write_bio_ECPrivateKey(bio, key, NULL, NULL, 0, NULL, NULL);
  17. BIO_free(bio);
  18. // 读取公钥
  19. bio = BIO_new_file("public.pem", "r");
  20. EC_KEY *public_key = PEM_read_bio_EC_PUBKEY(bio, NULL, NULL, NULL);
  21. BIO_free(bio);
  22. // 读取私钥
  23. bio = BIO_new_file("private.pem", "r");
  24. EC_KEY *private_key = PEM_read_bio_ECPrivateKey(bio, NULL, NULL, NULL);
  25. BIO_free(bio);
  26. // 加密数据
  27. std::string message = "Hello, World!";
  28. size_t ciphered_length = message.size() + EVP_MAX_IV_LENGTH + EVP_MAX_BLOCK_LENGTH;
  29. unsigned char ciphered[ciphered_length];
  30. EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
  31. EVP_SealInit(ctx, EVP_aes_256_cbc(), &ciphered[0], &ciphered_length, (unsigned char*)&ciphered[EVP_MAX_IV_LENGTH], &public_key, 1);
  32. EVP_SealUpdate(ctx, &ciphered[EVP_MAX_IV_LENGTH], &ciphered_length, (unsigned char*)message.c_str(), message.size());
  33. EVP_SealFinal(ctx, &ciphered[EVP_MAX_IV_LENGTH + ciphered_length], &ciphered_length);
  34. EVP_CIPHER_CTX_free(ctx);
  35. //解密数据
  36. size_t ciphered_length = sizeof(ciphered);
  37. size_t deciphered_length = ciphered_length - EVP_MAX_IV_LENGTH - EVP_MAX_BLOCK_LENGTH;
  38. unsigned char deciphered[deciphered_length];
  39. EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
  40. EVP_OpenInit(ctx, EVP_aes_256_cbc(), &ciphered[0], ciphered_length, (unsigned char*)&ciphered[EVP_MAX_IV_LENGTH], private_key);
  41. EVP_OpenUpdate(ctx, &deciphered[0], &deciphered_length, &ciphered[EVP_MAX_IV_LENGTH], ciphered_length);
  42. EVP_OpenFinal(ctx, &deciphered[deciphered_length], &deciphered_length);
  43. EVP_CIPHER_CTX_free(ctx);
  44. std::string message(reinterpret_cast<char*>(deciphered), deciphered_length);
  45. std::cout << message << std::endl;
  46. return 0;
  47. }

        在这个例子中,我们首先读取公钥和私钥,然后使用 EVP_OpenInitEVP_OpenUpdateEVP_OpenFinal 函数来解密数据。

2.4.3 DSA

        DSA的工作原理是,对于要发送的数字信息,先使用哈希函数对信息进行散列,然后使用私钥对散列后的信息进行签名,最后将签名和信息一起发送出去。接收方收到信息后,使用哈希函数对信息进行散列,然后使用公钥对签名进行验证。如果验证通过,就说明信息在传输过程中没有被篡改,否则就说明信息被篡改过。

        DSA的安全性主要来源于哈希函数的不可逆性和私钥的保密性。哈希函数的不可逆性意味着,无法通过散列后的信息来推断出原信息,这就使得攻击者无法通过篡改信息来绕过数字签名的保护。而私钥的保密性意味着,只有持有私钥的人才能对信息进行签名,这就使得攻击者无法伪造签名。

        DSA相对于其他数字签名算法,具有如下几个特点:

  1. 安全性:DSA是一种基于数学难题的算法,在设计上采用了严谨的数学证明,因此具有很高的安全性。

  2. 速度:DSA的运行速度比其他数字签名算法快得多,因此在对安全性要求不高的场景中,可以考虑使用DSA。

  3. 应用范围:DSA通常用于对安全性要求较高的场景,如金融、电子商务等。

  4. 密钥长度:DSA密钥长度一般较短,通常只有1024位或2048位。

        总的来说,DSA是一种安全性较高、速度较快的数字签名算法,适用于对安全性要求较高的场景。

        代码示例,该示例代码生成一对 DSA 密钥,然后使用私钥对一个消息进行签名,并使用公钥验证签名是否有效:

  1. #include <iostream>
  2. #include <cstring>
  3. #include <openssl/dsa.h>
  4. int main() {
  5. // 生成密钥对
  6. DSA* dsa = DSA_generate_parameters(1024, NULL, 0, NULL, NULL, NULL, NULL);
  7. DSA_generate_key(dsa);
  8. // 获取私钥和公钥
  9. const BIGNUM* priv_key = DSA_get0_priv_key(dsa);
  10. const BIGNUM* pub_key = DSA_get0_pub_key(dsa);
  11. // 准备待签名的数据
  12. const char* message = "Hello, World!";
  13. int message_len = strlen(message);
  14. // 使用私钥对数据进行签名
  15. unsigned char sig[1024];
  16. unsigned int sig_len;
  17. if (!DSA_sign(0, (unsigned char*) message, message_len, sig, &sig_len, dsa)) {
  18. std::cerr << "Failed to sign message" << std::endl;
  19. return 1;
  20. }
  21. // 使用公钥验证签名
  22. if (DSA_verify(0, (unsigned char*) message, message_len, sig, sig_len, dsa) != 1) {
  23. std::cerr << "Failed to verify signature" << std::endl;
  24. return 1;
  25. }
  26. std::cout << "Signature verification succeeded" << std::endl;
  27. DSA_free(dsa);
  28. return 0;
  29. }

2.4.4 其他非对称加密算法

        DH密钥交换算法:DH(Diffie-Hellman)密钥交换算法是一种用于在两个计算机之间安全地交换密钥的方法,可以让两个计算机之间在不安全的信道上交换密钥。这种算法的基本原理是,两个计算机之间共享一个大质数和一个底数,然后分别生成一个随机的私钥,并使用这个私钥和共享的大质数以及底数进行计算,得到一个公钥。然后,两个计算机之间交换它们自己的公钥,并使用对方的公钥和自己的私钥计算出一个密钥。由于这种算法使用的是大质数和底数,并且使用了私钥和公钥,因此即使被拦截者知道了共享的大质数和底数,也无法计算出密钥。这使得两个计算机之间可以在不安全的信道上安全地交换密钥。

        Elgamal加密算法:基于大数分解的困难性。在这种算法中,用户有两个密钥:公钥和私钥。公钥是用户分享给其他人的,而私钥是用户保留的。加密过程中,用户使用公钥加密消息,并使用私钥解密消息。Elgamal加密算法的流程如下:

  1. 用户选择一个大质数p和一个原根g(即满足g^(p-1) ≡ 1 (mod p)的数)。
  2. 用户随机选择一个私钥x,并计算出公钥y=g^x (mod p)。
  3. 用户要发送的消息是m,用户随机选择一个数k,并计算出a=g^k (mod p)和b=m*y^k (mod p)。 a和b就是加密后的消息。
  4. 用户将a和b发送给接收者。
  5. 接收者使用公钥y和私钥x解密消息,计算出m=b*a^(-x) (mod p)。

        Elgamal加密算法的安全性依赖于大数分解的困难性。因此,在选择p和g时,应选择足够大的数,以保证安全性。

三. 总结

        对称加密算法是一种加密方式,它使用相同的密钥来加密和解密数据。这意味着,如果将数据加密使用特定的密钥,则需要使用相同的密钥来解密该数据。对称加密算法通常被认为是快速的,但是它的主要缺点是,密钥必须在发送方和接收方之间安全地传递。常见的对称加密算法:AES、DES等。

        非对称加密算法是另一种加密方式,它使用一对密钥:公钥和私钥。数据可以使用公钥加密,但是只能使用私钥解密。这意味着,如果将数据加密使用特定的公钥,则可以使用与该公钥对应的私钥来解密该数据。非对称加密算法通常被认为是安全的,因为私钥不会被泄露。然而,它的主要缺点是,它通常比对称加密算法慢得多。常见的非对称加密算法有RSA、DSA、ECC等。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/698825
推荐阅读
相关标签
  

闽ICP备14008679号