openssl C++ DSA对指定文件内容签名和解签

  • 用DSA私钥对指定文件签名
  • 用DSA公钥验证签名
  • 用DSA公钥验证解签后的信息是否与机器码一致

DSA密钥对的生成请参考我这篇文章openssl在windows上生成RSA密钥、DSA密钥

用DSA私钥对指定文件签名

//DSA用私钥对文件内容签名
#pragma warning(disable:4996)
#include <iostream>
#include <fstream>
#include <openssl/dsa.h>
#include <openssl/pem.h>using namespace std;/*
函数名:DSA_sign
函数功能:用openssl的DSA接口读取DSA私钥,对指定文件内容进行签名,将签名保存到另一个文件中
输入参数:None
返回参数:bool 若签名成功,返回true,否则返回false
作者:Leo Ma
时间:2019.09.15
*/bool DSA_sign(string input_file,string sign_file)
{DSA* dsa_private_key = DSA_new();//定义DSA私钥unsigned char* input_string = new unsigned char;//定义要签名的字符串unsigned char* sign_string;//定义签名后的字符串unsigned int sig_len;//签名长度//从文件中读取DSA私钥BIO *priio;//Binary IOpriio = BIO_new_file("dsa_private_key.pem", "rb");dsa_private_key = PEM_read_bio_DSAPrivateKey(priio, &dsa_private_key, NULL, NULL);//从文件中读取要签名的内容,放在input_string中ifstream fin(input_file);if (!fin.is_open()){cout << "WARNING! NOT FOUND CHECK FILE,PLEASE CONTACT TO THE ADMISTRATOR!!!" << endl;return 0;}fin >> input_string;fin.close();//为签名后的字符串sign_string分配内存,如果不能正常分配内存,DSA_sign()将返回falsesign_string = (unsigned char*)calloc(DSA_size(dsa_private_key), sizeof(unsigned char));if (sign_string == NULL){fprintf(stderr, "Unable to allocate memory for sign_string\n");return false;//exit(-1);}//对input_string进行签名//DSA_sign输入参数:签名类型,要签名的字符串地址,要签名的字符串长度,签名后的字符串存放地址,签名后的字符串长度,私钥//如果签名失败,DSA_sign()将返回0,DSA_sign()将返回falseif (DSA_sign(0, input_string, strlen((char*)input_string),sign_string, &sig_len, dsa_private_key) == 0){fprintf(stderr, "Sign Error.\n");return false;//exit(-1);}//将签名后的字符串内容保存到一个文件中ofstream fout;fout.open(sign_file);fout << sign_string;fout.close();return true;
}int main(int argc, char** argv)
{DSA_sign("check_file.txt", "checked_file.txt");system("pause");
}

用DSA公钥验证签名

#pragma warning(disable:4996)
#include <iostream>
#include <fstream>
#include <openssl/dsa.h>
#include <openssl/pem.h>
#include <string>using namespace std;/*
函数名:DSA_verify_general
函数功能:用openssl的DSA接口验证解签后的信息是否与给定信息相同
输入参数:    string sign_file 签名文件string verify_string 给定的验证信息
返回参数:bool 若验证通过,返回true,否则返回false
作者:Leo Ma
时间:2019.09.15
*/bool DSA_verify_general(string sign_file, string verify_string)
{//将DSA公钥写死在文件中//把DSA公钥文件内容复制到下面的字符串里,将多余的空格(这是VS编辑器的问题)删掉,换行符遵循UNIX(LF)格式,即使用\n换行string dsa_public_key_string = "-----BEGIN PUBLIC KEY-----\nMIIBtjCCASsGByqGSM44BAEwggEeAoGBAKenvEftAsim1cta2VzV+SCSiwJZFq6v\n+UvbdOTkM+mB9vq4NcV1mOEgPyXczgb+dU/Mn7Y0Zi5CkvCe18YyjaillKfGjVCt\n9ftffA/ML3axyfxsiPAuX0I1GRWJk6qbFaXImUAKUAGUiK1yKtJPnXIbnIQBYxji\nAXUcV6Pa6KwfAhUAhHBmLP8lIBIso865Bz7z5XQMKmkCgYBZiMp+oVyEuzZ8eS1d\nBWvbyKk/gnvGMxv10o/X1dWiD7JlT9iUl6J1kh8BnEIB6D4+zXStgq/g/t8+j/fK\nbwmin/zTC5LrzPtvzS2nsCEM4jL5UJzil24k3F8AQX5PUCt+TOwA0DudLz59K+An\nME+CxAPrCkcjg2tmco1RwO1QhQOBhAACgYA3ix4u+0IrSKDI605qCUgmBBbD3YlK\niACidMGZpzZnTaY3GzFt5m/Yn8o2mRfU2/Ouhssuum7uKXep4N9OhidM76ErPbpV\nIHP7n6fWx09MdLz5HkOmomVI8s9gQEog89Y9sw5KMymxln44QGyJPRqnRIKK+h58\ncX/Uar7hPftz7A==\n-----END PUBLIC KEY-----\n";ofstream public_key_file;public_key_file.open("dsa_public_key.pem");public_key_file << dsa_public_key_string;public_key_file.close();//从刚写好的文件中读取DSA公钥DSA* dsa_public_key = DSA_new();BIO *pubio;//Binary IOpubio = BIO_new_file("dsa_public_key.pem", "rb");dsa_public_key = PEM_read_bio_DSA_PUBKEY(pubio, &dsa_public_key, NULL, NULL);/*//另一种读取DSA公钥的方法DSA* dsa_public_key = DSA_new();FILE *pubio;pubio = fopen("dsa_public_key.pem", "rb");dsa_public_key = PEM_read_DSA_PUBKEY(pubio, &dsa_public_key, NULL, NULL);*///从文件中读取DSA签名string sign_string;ifstream fin(sign_file);if (!fin.is_open()){cout << "WARNING! NOT FOUND CHECKED FILE,PLEASE CONTACT TO THE ADMISTRATOR!!!" << endl;return 0;}fin >> sign_string;fin.close();//用DSA公钥解签并验证是否跟验证信息一致int is_valid_signature = DSA_verify(0, (const unsigned char*)verify_string.data(), verify_string.length(),(const unsigned char*)sign_string.data(), sign_string.length(), dsa_public_key);//返回一个bool型变量if (is_valid_signature == 1)return true;else return false;
}int main()
{if (DSA_verify_general("checked_file.txt", "BFEBFBFF000906E9E0D55EC381F0")){cout << "VERIFY SUCCESSFULLY!!!" << endl;}else{cout << "VERIFY FAIL!!!" << endl;}system("pause");return 0;
}

用DSA公钥验证解签后的信息是否与机器码一致

关于如何获取运行机器的机器码请参考我这篇文章C++在windows下获得运行主机的硬件信息:CPU序列号、MAC地址、硬盘序列号、主板序列号

#pragma warning(disable:4996)
#include <iostream>
#include <fstream>
#include <string>
#include "get hardware information/get_hardware_information.h"
#include <openssl/dsa.h>
#include <openssl/pem.h>
using namespace std;/*
函数名:my_get_hardware_information
函数功能:获得本机硬件信息:CPU序列号,Mac地址,主板序列号,硬盘序列号
输入参数:None
返回参数:string类型,CPU序列号+Mac地址
作者:Leo Ma
时间:2019.09.15
*/
string my_get_hardware_information()
{char lpszCpu[128] = "";char lpszMac[128] = "";char lpszBaseBoard[128] = "";char lpszHDSerial[128] = "";GetCpuSerialByCmd(lpszCpu, 128);GetMacByCmd(lpszMac, 128);GetBaseBoardByCmd(lpszBaseBoard, 128);GetHDSerialByCmd(lpszHDSerial);//cout << "CPU ID is " << lpszCpu << endl;//cout << "MAC ID is " << lpszMac << endl;//cout << "Base Board ID is " << lpszBaseBoard << endl;//cout << "HD Serial is " << lpszHDSerial << endl;string string_return;string_return.assign(lpszCpu);string_return.append(lpszMac);//string_return.append("\0");//string_return.append(lpszBaseBoard);//string_return.append(lpszHDSerial);//cout << string_return << endl;return string_return;
}/*
函数名:DSA_verify_machine
函数功能:用openssl的DSA接口验证当前机器码是否与解签的机器码一致
输入参数:None
返回参数:bool 若验证通过,返回true,否则返回false
作者:Leo Ma
时间:2019.09.15
*/bool DSA_verify_machine()
{//读取本机机器码string hardware_info;hardware_info = my_get_hardware_information();//只获取CPU ID和Mac地址//hardware_info = get_hardware_information("check_file.txt");//获取CPU ID、Mac地址、主板序列号、硬盘序列号,并且生成文件//将DSA公钥写死在文件中//把DSA公钥文件内容复制到下面的字符串里,将多余的空格(这是VS编辑器的问题)删掉,换行符遵循UNIX(LF)格式,即使用\n换行string dsa_public_key_string = "-----BEGIN PUBLIC KEY-----\nMIIBtjCCASsGByqGSM44BAEwggEeAoGBAKenvEftAsim1cta2VzV+SCSiwJZFq6v\n+UvbdOTkM+mB9vq4NcV1mOEgPyXczgb+dU/Mn7Y0Zi5CkvCe18YyjaillKfGjVCt\n9ftffA/ML3axyfxsiPAuX0I1GRWJk6qbFaXImUAKUAGUiK1yKtJPnXIbnIQBYxji\nAXUcV6Pa6KwfAhUAhHBmLP8lIBIso865Bz7z5XQMKmkCgYBZiMp+oVyEuzZ8eS1d\nBWvbyKk/gnvGMxv10o/X1dWiD7JlT9iUl6J1kh8BnEIB6D4+zXStgq/g/t8+j/fK\nbwmin/zTC5LrzPtvzS2nsCEM4jL5UJzil24k3F8AQX5PUCt+TOwA0DudLz59K+An\nME+CxAPrCkcjg2tmco1RwO1QhQOBhAACgYA3ix4u+0IrSKDI605qCUgmBBbD3YlK\niACidMGZpzZnTaY3GzFt5m/Yn8o2mRfU2/Ouhssuum7uKXep4N9OhidM76ErPbpV\nIHP7n6fWx09MdLz5HkOmomVI8s9gQEog89Y9sw5KMymxln44QGyJPRqnRIKK+h58\ncX/Uar7hPftz7A==\n-----END PUBLIC KEY-----\n";ofstream public_key_file;public_key_file.open("dsa_public_key.pem");public_key_file << dsa_public_key_string;public_key_file.close();//从刚写好的文件中读取DSA公钥DSA* dsa_public_key = DSA_new();BIO *pubio;//Binary IOpubio = BIO_new_file("dsa_public_key.pem", "rb");dsa_public_key = PEM_read_bio_DSA_PUBKEY(pubio, &dsa_public_key, NULL, NULL);/*//另一种读取DSA公钥的方法DSA* dsa_public_key = DSA_new();FILE *pubio;pubio = fopen("dsa_public_key.pem", "rb");dsa_public_key = PEM_read_DSA_PUBKEY(pubio, &dsa_public_key, NULL, NULL);*///从文件中读取DSA签名string sign_string;ifstream fin("checked_file.txt");if (!fin.is_open()){cout << "WARNING! NOT FOUND CHECKED FILE,PLEASE CONTACT TO THE ADMISTRATOR!!!" << endl;return 0;}fin >> sign_string;fin.close();//用DSA公钥验证签名和读取机器码是否一致int is_valid_signature = DSA_verify(0, (const unsigned char*)hardware_info.data(), hardware_info.length(),(const unsigned char*)sign_string.data(), sign_string.length(), dsa_public_key);//返回一个bool型变量if (is_valid_signature == 1)return true;else return false;
}int main()
{if (DSA_verify_machine()){cout << "验证通过,假装执行代码" << endl;}else{cout << "CHECKED FAIL!PLEASE CONTACT THE ADMINASTOR!!!" << endl;}system("pause");return 0;
}

openssl C++ DSA对指定文件内容签名和解签相关推荐

  1. python中多对多替换_Python对指定文件内容进行全局替换

    关于对指定文件内容进行全局替换的Python实现具体解释都附在代码里了 代码如下: import os import sys cs = sys.argv old_cs = cs[1] # 将要替换掉的 ...

  2. python文件内容 替换,Python对指定文件内容进行全局替换

    关于对指定文件内容进行全局替换的Python实现具体解释都附在代码里了 代码如下: import os import sys cs = sys.argv old_cs = cs[1] # 将要替换掉的 ...

  3. git如何合并指定文件内容_git小技巧--如何从其他分支merge个别文件或文件夹

    在实际工作中,一个大型的项目或版本迭代可能不是一次上线,可能会分好几次上线,这时候就会涉及创建多个分支,进行分别开发. 创建分支 功能分为2个分支,分别为A.B. A上面有个列表页功能 B上面有个详情 ...

  4. git如何合并指定文件内容_Git合并指定文件到另一个分支

    经常被问到如何从一个分支合并特定的文件到另一个分支.其实,只合并你需要的那些commits,不需要的commits就不合并进去了. 合并某个分支上的单个commit 首先,用git log或sourc ...

  5. JAVA 实现签名和解签

    学习网址: http://www.ibm.com/developerworks/cn/java/l-security/ 1.签名:     用他私人密钥 (prikey) 对他所确认的信息 (info ...

  6. 【FTP工具类】提供FTP服务器的连接, 查找文件目录,及读取文件内容等操作

    介绍:FTP工具类,提供FTP服务器的连接, 查找文件目录,及读取文件内容等操作. 应用场景: 通过FTP连接需要获取文件目录列表 通过FTP连接读取指定文件内容 递归读取遍历服务器上所有文件 其他功 ...

  7. 使用FileSystemWatcher 实现对指定路径下指定文件的监视

    一.问题描述 我们想要实现实时监测指定路径下的指定文件内容,但是这些文件的更改是没有规律的,如果单独开启一个线程间隔500毫秒去监测读取进行后续的业务处理,这样的话就会存在IO问题和出现多个无效的业务 ...

  8. Java 实现 RSA 非对称加密算法-加解密和签名验签

    1. 非对称加密算法简介 非对称加密算法又称现代加密算法,是计算机通信安全的基石,保证了加密数据不会被破解.与对称加密算法不同,非对称加密算法需要两个密钥:公开密钥(publickey)和私有密(pr ...

  9. RSACryptoServiceProvider加密解密签名验签和DESCryptoServiceProvider加解密

    RSACryptoServiceProvider加密解密签名验签和DESCryptoServiceProvider加解密 原文:RSACryptoServiceProvider加密解密签名验签和DES ...

最新文章

  1. 分别用BFS和DFS求给定的矩阵中“块”的个数
  2. R语言使用gt包和gtExtras包优雅地、漂亮地显示表格数据:使用gtExtras包添加一个图,显示表中某一列中的数字、并自定义表格数据显示的主题格式、并自定义数值数据的格式(例如百分比)
  3. KEIL MDK LIB库文件的制作
  4. BPI:bit for Webduino WEB:Bit 教育版平台正式发布,支持离线安装使用
  5. Windows 平台下 Go 语言的安装和环境变量设置
  6. SAP 采购订单税金抓取方法
  7. B04_NumPy从已有的数组创建数组(numpy.asarray,numpy.frombuffer,numpy.fromiter)
  8. Tomcat 6.0 简介
  9. Java OutputStreamWriter flush()方法与示例
  10. 阅文启动“2022全球作家孵化项目” 加速网络文学出海
  11. 数据库性能自动压测-Oracle swingbench篇
  12. ELK详解(二十三)——elastalert告警优化
  13. Android 控件 之 菜单(Menu)
  14. c语言跑酷小游戏代码,跑酷游戏代码
  15. android开发实战-记账本APP(二)
  16. 详解2021华为笔试三道编程题
  17. 实现仿微信朋友圈评论输入框
  18. 工商银行在线支付接口
  19. AI:从游戏引擎--到AI
  20. 《Adobe After Effects CS6中文版经典教程》——2.9 渲染合成图像

热门文章

  1. 5G 3GPP USIM Tuak算法code
  2. 流程图怎么制作?常见方式介绍
  3. Linux下hp打印机驱动hplip分析
  4. vscode 找不到 python 解析器
  5. 22.9.18——论坛
  6. 【 C++ 】类和对象(中)—— 类的6个默认成员函数
  7. C语言入门篇 初识C语言
  8. 一步步学习微软InfoPath2010和SP2010--第五章节--添加逻辑和规则到表单(6)--使用规则创建多视图样式向导表单
  9. 网站被挂黑链会引起哪些后果
  10. Mac Cornerstone详细使用说明,图文教程