zoukankan      html  css  js  c++  java
  • C# RSA加密解密 使用Openssl密钥 XML格式密钥和 openssl pem格式密钥互转, C#RSA获取PEM格式密钥

    因为实际的需求,需要使用 RSA 的非对称加密信息。所以有了这边文章,简单的说下什么是非对称加密:

    非对称加密RSA

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

    如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密。 
    如果用私有密钥对数据进行加密,只有用对应的私有密钥才能解密。

    特点: 
    算法强度复杂,安全性依赖于算法与密钥。 
    加密解密速度慢。

    与对称加密算法的对比: 
    对称加密只有一种密钥,并且是非公开的,如果要解密就得让对方知道密钥。 
    非对称加密有两种密钥,其中一个是公开的。

    RSA应用场景: 
    由于RSA算法的加密解密速度要比对称算法速度慢很多,在实际应用中,通常采取 
    数据本身的加密和解密使用对称加密算法(AES)。 
    用RSA算法加密并传输对称算法所需的密钥。

    这部分的内容可以参考下面的博客,我从这个博客里受益良多。

    https://www.cnblogs.com/shoshana-kong/p/10934550.html

    好了正式开始今天的内容

    一般我们在C#里都是这么使用的,假如我们需要对密码进行加密操作

    			// 包含公钥和私钥的rsa对象
    			RSACryptoServiceProvider RSA = new RSACryptoServiceProvider( );
    			// 等待加密的密码
    			byte[] password = Encoding.UTF8.GetBytes( "123456" );
    			// 对密码进行加密
    			byte[] encrypt = RSA.Encrypt( password, false );
    
    			// 对密码进行解密
    			string password2 = Encoding.UTF8.GetString( RSA.Decrypt( encrypt, false ) );
    			Console.WriteLine( password2 );
    

     

    这就是用同一个的密钥进行加密解密操作。但是通常时候,我们会把公钥给客户端,客户端加密之后,把密码发送给服务器,服务器实现解密,然后进行其他的操作。

     

    			// 包含公钥和私钥的rsa对象
    			RSACryptoServiceProvider RSA = new RSACryptoServiceProvider( );
    			// 生成公钥给客户端使用,注意,就是XML格式的
    			string publicKey = RSA.ToXmlString( false );
    			Console.WriteLine( publicKey );
    
    			// 客户端进行加密操作
    			RSACryptoServiceProvider RsaClient = new RSACryptoServiceProvider( );
    			RsaClient.FromXmlString( publicKey );
    			// 等待加密的密码
    			byte[] password = Encoding.UTF8.GetBytes( "123456" );
    			// 对密码进行加密
    			byte[] encrypt = RsaClient.Encrypt( password, false );
    
    			// 服务器端收到 encrypt 对密码进行解密
    			string password2 = Encoding.UTF8.GetString( RSA.Decrypt( encrypt, false ) );
    			Console.WriteLine( password2 );
    

      运行之后看看

    可以,没有什么问题,接下来,我们看看标准的 OPENSSL 生成的密钥的操作

    官网:https://www.openssl.org/

    下载地址:http://slproweb.com/download/Win64OpenSSL_Light-1_1_1L.msi

    安装好之后,我们就可以进行操作了

    我先生成一个私钥

    openssl genrsa -out test.key 1024
    

     

     我们再生成一个公钥

    openssl rsa -in test.key -pubout -out test_pub.key
    

    好了,我们公钥私钥都有了,这时候已经可以加密解密了。

    我们创建一个文件 pwd.txt  存储个密码 123456

     文本文件编码为UTF8

    我们现在可以进行加密操作了

    openssl rsautl -encrypt -in pwd.txt -inkey test_pub.key -pubin -out pwd.en
    

      执行之后就加密成功了

    好了,加密成功了,现在我们来看下这个密钥信息,先看私钥

     公钥

     

     emmmm,好像和我们在C#看到的密钥不一样啊,我想在C#里,也使用这个公钥私钥,怎么办????

    在经过我几天的研究之后,给大家提供了一个库,来快速方便的解决这个问题

    就是大名鼎鼎的 HslCommunication

    至于如何安装,可以参考下面的文章:

    如果需要教程:Nuget安装教程:http://www.cnblogs.com/dathlin/p/7705014.html

    组件的api地址:http://api.hslcommunication.cn

    有个demo程序的源代码:

    https://github.com/dathlin/HslCommunication

    在demo里提供了测试的界面

    好了,想必您已经安装了HslCommunication了,现在继续操作

    using System.Security.Cryptography;
    using HslCommunication.Core.Security;
    

      

    只要using这两个就可以了,如果需要扩展方法,最好再using一个

    using HslCommunication;
    

      

    代码里应该怎么写呢?

    			// 把私钥拷贝过来,就可以对数据进行解析了。
    			RSACryptoServiceProvider rsa = RSAHelper.CreateRsaProviderFromPrivateKey( @"-----BEGIN RSA PRIVATE KEY-----
    MIICXAIBAAKBgQCedjrK/6w7gMapQsN/vyvvohbeLfdEZ/hk3AP6QeKa0D7S8cCa
    dOhbM279wXPwwH7S9zLMpEl6BPYk2V0uZzjyMgAQl5dTZZj4esgoJJ9fpHFJlo0/
    mSRzv848/s+UmNniYZN7n8764HMZr5C5J67Ky0QOVHPBUMrvrxmXpFJ7zQIDAQAB
    AoGAebqnVZRtEdTOR+6S0krgjJi+6nTzM6iPJ6PgploAox8Ac/nlFIJkkNMFG4iF
    8Vde1d+yNYSrMUIoeIxGScRf+HBngpjSD2Zmdv1yOT2BaULxv+O4HIG5KUt9X+WW
    FrwB0KYNnSR5ggwFIuUSY9kEdEghvE7mAbTCImwCQVHhD50CQQDTJLEwWz+nlldI
    Z4fVr2mPPJYW+MVe2Zj4f8wMQUct3c/Ys6a3XG9yO+qGUjMrZQD0jXLoTNeJSSW9
    3XqAU97LAkEAwCBilv5yY/ZTyNV5WqzTiglrUhm7R6RZWAUIjeztCwT1Hn3UQbW1
    aK1aXIoV6sEAsmbfmQekmvgSvLrJnCtkxwJBAKaxZSIkKBEK5EXJVrghEFmBH41r
    QYcsi1REsLdMIgHYCGuxCYHhfCrXmsQIyVUNHL/1nC5B3DgKg71tyXTewhkCQA+J
    ju+PHEkhPp1bRjkjCOh84oT9N7wPeno3zf1MT884U2pn2qaFv2n7uvcI48TcXuYO
    k76Yc6NktH82y98pUzkCQDd5JRD2McDLPkAIJERk7lSgkxyt0a8lpD8o/kKYBLtO
    am6KPGMGIhEOpgsRXMJYCk7v9gFoPWhcxX4RsMlhsk8=
    -----END RSA PRIVATE KEY-----" );
    			Console.WriteLine( Encoding.UTF8.GetString( rsa.Decrypt( File.ReadAllBytes( @"E:SSLpwd.en" ), false ) ) );
    

      运行一下,看看结果

     

    如何创建公钥的RSA对象呢?

    			// 把公钥数据拷贝过来,就可以加密了
    			RSACryptoServiceProvider rsaPublic = RSAHelper.CreateRsaProviderFromPublicKey( @"-----BEGIN PUBLIC KEY-----
    MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCedjrK/6w7gMapQsN/vyvvohbe
    LfdEZ/hk3AP6QeKa0D7S8cCadOhbM279wXPwwH7S9zLMpEl6BPYk2V0uZzjyMgAQ
    l5dTZZj4esgoJJ9fpHFJlo0/mSRzv848/s+UmNniYZN7n8764HMZr5C5J67Ky0QO
    VHPBUMrvrxmXpFJ7zQIDAQAB
    -----END PUBLIC KEY-----" );
    			// 我随便加密个数据
    			string pwd = "在座的都是帅哥美女";
    			byte[] encrypt = rsaPublic.Encrypt( Encoding.UTF8.GetBytes( pwd ), false );
    
    			// 对上面的加密数据进行解析
    			// 把私钥拷贝过来,就可以对数据进行解析了。
    			RSACryptoServiceProvider rsa = RSAHelper.CreateRsaProviderFromPrivateKey( @"-----BEGIN RSA PRIVATE KEY-----
    MIICXAIBAAKBgQCedjrK/6w7gMapQsN/vyvvohbeLfdEZ/hk3AP6QeKa0D7S8cCa
    dOhbM279wXPwwH7S9zLMpEl6BPYk2V0uZzjyMgAQl5dTZZj4esgoJJ9fpHFJlo0/
    mSRzv848/s+UmNniYZN7n8764HMZr5C5J67Ky0QOVHPBUMrvrxmXpFJ7zQIDAQAB
    AoGAebqnVZRtEdTOR+6S0krgjJi+6nTzM6iPJ6PgploAox8Ac/nlFIJkkNMFG4iF
    8Vde1d+yNYSrMUIoeIxGScRf+HBngpjSD2Zmdv1yOT2BaULxv+O4HIG5KUt9X+WW
    FrwB0KYNnSR5ggwFIuUSY9kEdEghvE7mAbTCImwCQVHhD50CQQDTJLEwWz+nlldI
    Z4fVr2mPPJYW+MVe2Zj4f8wMQUct3c/Ys6a3XG9yO+qGUjMrZQD0jXLoTNeJSSW9
    3XqAU97LAkEAwCBilv5yY/ZTyNV5WqzTiglrUhm7R6RZWAUIjeztCwT1Hn3UQbW1
    aK1aXIoV6sEAsmbfmQekmvgSvLrJnCtkxwJBAKaxZSIkKBEK5EXJVrghEFmBH41r
    QYcsi1REsLdMIgHYCGuxCYHhfCrXmsQIyVUNHL/1nC5B3DgKg71tyXTewhkCQA+J
    ju+PHEkhPp1bRjkjCOh84oT9N7wPeno3zf1MT884U2pn2qaFv2n7uvcI48TcXuYO
    k76Yc6NktH82y98pUzkCQDd5JRD2McDLPkAIJERk7lSgkxyt0a8lpD8o/kKYBLtO
    am6KPGMGIhEOpgsRXMJYCk7v9gFoPWhcxX4RsMlhsk8=
    -----END RSA PRIVATE KEY-----" );
    			Console.WriteLine( Encoding.UTF8.GetString( rsa.Decrypt( encrypt, false ) ) );
    

      在运行下

    这样通过openssl或是其他的程序生成的公钥私钥,都可以给C#使用了。

    还有个细节是

    当C#生成一个RSA对象之后,就默认创建了公钥私钥了。虽然C#提供了导出XML格式的公钥私钥,但是这不是我们想要的,或是提供给别人,就蒙圈了

    那么如何导出PEM的公钥私钥数据呢?

    			// 生成一个rsa算法的私钥和公钥
    			RSACryptoServiceProvider rsa = new RSACryptoServiceProvider( 1024 );
    			// 下面两种方法都可以导出私钥的
    			// byte[] privateKey = RSAHelper.GetPrivateKeyFromRSA( rsa );
    			byte[] privateKey = rsa.GetPEMPrivateKey( );
    			Console.WriteLine( Convert.ToBase64String( privateKey ) );
    			// 导出公钥
    			// byte[] publicKey = RSAHelper.GetPublicKeyFromRSA( rsa );
    			byte[] publicKey = rsa.GetPEMPublicKey( );
    			Console.WriteLine( "==============================以下是公钥" );
    			Console.WriteLine( Convert.ToBase64String( publicKey ) );
    

      

     运行一下看看

    这个密钥生成到底对不对呢?

    我们把密钥拷贝到SSL文件路径下

     重新加密解密看看

    openssl rsautl -encrypt -in pwd.txt -inkey test_pub.key -pubin -out pwd.en
    

      解密

    openssl rsautl -decrypt -in pwd.en -inkey test.key -out pwd1.txt
    

     可以看到非常的准确,再尝试下,C#解析密钥

     还是之前的代码,但是私钥换了

     非常正确!!

    经过测试,符合要求,感谢使用。

      

  • 相关阅读:
    JS LeetCode 1423. 可获得的最大点数简单题解
    SpringBoot 学集 (第六章) Docker
    Linux 学记 (第三章)
    Linux 学记 (第二章)
    Linux 学记 (第一章)
    SpringBoot 学集 (第五章) Web开发续
    SpringBoot 学集 (第四章)Web开发
    SpringBoot 学集 (第三章) 日志框架
    SpringBoot 学集 (第二章) 配置文件
    SpringBoot 学集 (第一章)
  • 原文地址:https://www.cnblogs.com/dathlin/p/15227913.html
Copyright © 2011-2022 走看看