Visual Studio C++ RSA加解密方案

来源:互联网 发布:加密狗共享usb端口 编辑:程序博客网 时间:2024/06/06 13:12

本文的应用场景是,Unity c#向vc++ 工程传递用户名和密码,可能会面临的安全性问题:

假如第三方对dll进行替换,c#的账号密码直接往下传,可能导致用户密码泄露的风险。

针对此种情况,对用户名和密码在C#层进行加密,并在C++ dll库中进行解密,从而在一定程度上规避此风险。

C++ RSA加解密方案

  1. 支持.net的RSACryptoServiceProvider

  2. cryto++ library

  3. openssl

第一种方案,C++RSA 跟C#版的RSA配套,用起来极为方便,但是依赖.net架构。需要依赖.net环境,将工程设置为支持clr。

后两种方案,是第三方集成库。当前使用较为广泛的方法是openssl,下面着重介绍openssl在RSA上的使用。

Openssl编译配置

按顺序执行下列命令

d:\openssl-1.0.1e> perl Configure VC-WIN32 no-asm –prefix=d:\openssl_lib (存放编译后的库文文件目录)

d:\openssl-1.0.1e> ms\do_ms
d:\openssl-1.0.1e> nmake -f ms\ntdll.mak (编译动态库)
d:\openssl-1.0.1e> nmake -f ms\nt.mak (编译静态库)
装载openssl到指定的目录d:\opensll_lib中

d:\openssl-1.0.1e> nmake -f ms\ntdll.mak install

d:\openssl-1.0.1e> nmake -f ms\nt.mak install
(b)继续编译, 提示错误:

cryptlib.obj : error LNK2001: unresolved external symbol _OPENSSL_ia32_cpuid

out32dll/libeay32.dll : fatal error LNK1120: 1 unresolved externals

解决办法: 修改do_ms文件如下:

perl util/mkfiles.pl >MINFOperl util/mk1mf.pl debug no-asm VC-WIN32 >ms/nt.makperl util/mk1mf.pl debug dll no-asm VC-WIN32 >ms/ntdll.makperl util/mk1mf.pl debug no-asm VC-CE >ms/ce.makperl util/mk1mf.pl debug dll no-asm VC-CE >ms/cedll.makperl util/mkdef.pl 32 libeay > ms/libeay32.defperl util/mkdef.pl 32 ssleay > ms/ssleay32.def

集成OpenSSL

这里写图片描述

打开Project Property面板:

  1. Configuration Properties——VC++ Directories——Include Directories新增”d:\openssl_lib\include”(存放编译后的库文件的目录中);

  2. VC++ Directories ——”Library files”选择中新增目录”d:\openssl_lib\lib”;

  3. Configuration Properties ——Linker——Input——Additional Dependencies,添加libeay32.lib 和ssleay32.lib两个库即可。

Openssl生成公私密钥和证书

安装openssl,cmd执行openssl

OpenSSL>genrsa -out rsa_private_key.pem 1024

生成的pem文件如下:

-----BEGIN RSA PRIVATE KEY-----MIICXAIBAAKBgQDJsiBpRxfPFRh9DbmWizZbm5/HKxhpOOQMlmGo2LIuVWxXuzYjTyQ9Jfn+zDfIGG3NLkAHrpcW0U8figjCXb/dXptc/MabgwPIP1jL1uqTLgIYeVsTJm6vEzd7c/t81VaOJDjFkQlrlqdOsH5JnAlGtqITqXHSimbgBDUjtJW+qwIDAQABAoGAICuGGeSZ+pCd0ExhHo7jw6bFzEmmYhoN3agauYiemt9LIY8dqnIUEKC/CBHgj8y9rq1CzzbcqGoIGbq1fPLhCBAn1dkRePKKqSd1BM99oVwDP2YYBqzaUtPz1TYNq0Q9QqKuQgkWkPC+7QugnDzIuzlqO9+/wdugLd2UateZZqECQQD4qtEsMPrSu9g8yTjJOnyChYhQuUXbLalFlqSRnHWM7eIxqNkMjhPoK3sxGWWMNT410kNhxgWUZnMTbbXjO2E7AkEAz6S5JjIY/GhFxer9vxY3yjUW7Agtnk0zyi70RpbuvttdNjUxeXiGf/q3ilNJE2eWt2PaICb/c32PdCO5P5RBUQJBANZnmiErPikTM/f9W8wNdKupbQaFKNk5fpj0sYKnT6equHwu5K5xlnJ5gyeriSYiBjirydN0xPzWdORMlSaO3V8CQCobc1hljF+THaMXFkHr1YBx56YRun6BlWEIyIyQCvY1Md/ORawmXtARHas1XHpM5WlnHFKs1dyrt62LmQNloyECQAZEeNq5AyRGRq+oAPjMlGEUrKR/7w3zXdCO2nyCYtQXYkE4+ZBUeKBFgPEoHGUqY+yOD9xIg5d6rbf71Hh2kx0=-----END RSA PRIVATE KEY-----

2)把RSA私钥转换成PKCS8格式

OpenSSL> rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pemwriting RSA keyOpenSSL> pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM –nocryptEnter Encryption Password:Verifying - Enter Encryption Password:-----BEGIN ENCRYPTED PRIVATE KEY-----MIICoTAbBgkqhkiG9w0BBQMwDgQIsz6q/2JpXSACAggABIICgHPkfKkuH+Dn18q0k0xUIDmnKvApJlXlaRF1jo4wF1hbO0RThwr2r//AlScy5yoEeUMyhh5ae4yEzT7rU3nGYcnVV64AkwV/JMthpYNVPpb4OL8xbOyGbmU3UigoAhLo4/bDkiGDs9ZTRyDWp0QyOyFJZ0L7NhvWmkYsDUAahY/xjYQy3Cghk5pvhSQjhbAu3yaF3UtJNZhqGZCN/p7nrwG9Vt0Ys6nzUC4PQFafyZzdfl4l9f0WlCwWSRNy+s3hxLavJySt6ycGAbNLue3lGpnVPLCgwh5p5I3w9Aym96hDsAvMdqXg92mbeO22Tqz8MccVQqIYO+HpPXn7uH3aYx4sxjV/p+wUK/XlNL/XEoyw+WVJ4wxBBFGtZvk5lurCODdgFsZbfzGWO9gW5Y2kXp4FK9iVzhiS1YI5fn6yaKAUPB+jtj5xSrmtxhV7Q7N5YuJeFsGhXNpuQKxyXWyEbU2gbsuI0LYAr+r7M5LWSouYLne3NDfB1Op2oFwoz9j+p+drEgoByDWZQMo6ay4T928LdHQFgKYajtBkch2Z5lNwwUdaZwe8AalJVTM2otDE9QSpiOq4Sjmyu5OdKt3SesMEoCQSJ2SM3dqMqEIBf/YDtL4juFId0uffNW2BcpVrq5muJ0+xTtWmC75ZSsULmCwWzYTKe+OiG8r/Z7DVXY30onWfJnPJEGl3vyMGDDgacYQrN3qGMUGoJxzLMeEdt9xfTlpY4XO/DIUAPEWJtLN0XvHSKlqMtk/m124ugugLzi4SmWusYDTs1rS3MjpnNpSFYw12jBVcM95PCtuLmP7Ts9LXc5zbtpYIv8IP/S5RlasSQpCNfRLlADbBd6pH+PA=-----END ENCRYPTED PRIVATE KEY-----

3) 生成RSA公钥

输入命令rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem,

-----BEGIN PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDJsiBpRxfPFRh9DbmWizZbm5/HKxhpOOQMlmGo2LIuVWxXuzYjTyQ9Jfn+zDfIGG3NLkAHrpcW0U8figjCXb/dXptc/MabgwPIP1jL1uqTLgIYeVsTJm6vEzd7c/t81VaOJDjFkQlrlqdOsH5JnAlGtqITqXHSimbgBDUjtJW+qwIDAQAB-----END PUBLIC KEY-----

创建证书请求

openssl req -new -out cert.csr -key rsa_private_key.pemYou are about to be asked to enter information that will be incorporatedinto your certificate request.What you are about to enter is what is called a Distinguished Name or a DN.There are quite a few fields but you can leave some blankFor some fields there will be a default value,If you enter '.', the field will be left blank.-----Country Name (2 letter code) [AU]:86State or Province Name (full name) [Some-State]:GuangdongLocality Name (eg, city) []:ShenzhenOrganization Name (eg, company) [Internet Widgits Pty Ltd]:XfictionOrganizational Unit Name (eg, section) []:KCommon Name (eg, YOUR name) []:fictionEmail Address []:xfiction@gmail.comPlease enter the following 'extra' attributesto be sent with your certificate requestA challenge password []:xfiction8989An optional company name []:xfiction

这里写图片描述

自签署根证书(自签署,就是不通过CA认证中心自行进行证书签名,这里用是x509)

openssl x509 -req -in cert.csr -out public.der -outform der -signkey rsa_private_key.pem -days 3650Signature oksubject=/C=86/ST=Guangdong/L=Shenzhen/O=Xfiction/OU=K/CN=fiction/emailAddress=xfiction@gmail.comGetting Private key

XML到PEM的转换:

由于C#的RSACryptoServiceProvider所使用的是xml格式,openssl使用pem格式的秘钥。需要对秘钥进行转换。

可以直接通过线上转换工具RSA Key Converter(https://superdry.apphb.com/tools/online-rsa-key-converter)进行转换。

附上代码

RSAEncryptService rasService = new RSAEncryptService();string psdEncrpted = rasService.RSAEncryptStr(pwd); RSA* pPrivateRSA = createRSAWithMem(strPrivateKeyPerm);//string strPubEncode = "ZfBe7UOZzjdoKsnf90vQe47klfj9+EmmlBUA86IMhFIpceKB0NxLeGSivw0JUk7s9QN+CFPIRTkr1Z7gXgniGNlkbuZzZcIoao1kWkvRGM81KTPt0YS8v/2RAE83re/c6zby4fGmELx9S+t8HdiUovDQaKZgz2ycgomfCxyI7mw=";string strPubEncode = pwd;string strPrivateDecode;char strOrgData[1024] = { 0 };Private_Decrypt(pPrivateRSA, strPubEncode, strPrivateDecode);const char* decryptPwd = strPrivateDecode.c_str();

C#和c++代码见附件

参考文章

http://www.jianshu.com/p/faefcc58c79b

0 0
原创粉丝点击