NetCore 下使用RSA加密,解密;并且前端使用jsencrypt.js实现Rsa相关方法。

首先上资源

jsencrypt.js下载地址:https://github.com/travist/jsencrypt

第三方Rsa密钥生成工具:BouncyCastle.Crypto.dll,直接可以在NuGet中查找。

至于为什么用第三方工具生成密钥,是为了和jsencrypt配合。c#本身RSACryptoServiceProvider类生成的工具不能再jsencrypt中使用。

有关知识:http://www.cnblogs.com/dudu/p/dotnet-core-rsa-openssl.html

并且:(信息来源:https://www.jianshu.com/p/f22b4e565ec1)文中的生成RSAParameters方法来源于此。

  • RSACryptoServiceProvider
    在Windows 环境下依然可以使用RSACryptoServiceProvider, 但在Linux 环境下编译不过. 参考 dudu 的文章 .net core中使用openssl的公钥私钥进行加解密

  • FromXmlString方法和ToXmlString
    由于不在使用RSACryptoServiceProvider这两个方法不在提供,我们可以通过扩展方法来添加这两个方法,以处理C#生成的密钥.

这边引用BouncyCastle.Crypto.dll会在NuGet里有个警告提示,如图:

我在Centos7,和windows10 里测试过,可以使用,其他就不懂了。

这是BouncyCastle.Crypto.dll在NuGet相关信息:

好了开始上代码。

使用BouncyCastle.Crypto.dll生成PEM密钥字符串

 1             public static RSAKey GetKey()
 2             {
 3                 var key = new RSAKey();
 4                 Org.BouncyCastle.Crypto.Generators.RsaKeyPairGenerator g = new Org.BouncyCastle.Crypto.Generators.RsaKeyPairGenerator();
 5                 g.Init(new Org.BouncyCastle.Crypto.KeyGenerationParameters(new SecureRandom(), 1024));
 6                 var pair = g.GenerateKeyPair();
 7 
 8 
 9 
10                 TextWriter textWriter = new StringWriter();
11                 PemWriter pemWriter = new PemWriter(textWriter);
12                 pemWriter.WriteObject(pair.Private);
13                 pemWriter.Writer.Flush();
14 
15                 string privateKey = textWriter.ToString();
16                 key.privateKey = privateKey;
17 
18 
19                 TextWriter textpubWriter = new StringWriter();
20                 PemWriter pempubWriter = new PemWriter(textpubWriter);
21                 pempubWriter.WriteObject(pair.Public);
22                 pempubWriter.Writer.Flush();
23                 string pubKey = textpubWriter.ToString();
24                 key.publicKey = pubKey;
25 
26 
27 
28                 #region 使用该部分代码偶尔会在解析私钥时候发生“不正常数据”异常。
29                 //PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(pair.Private);
30                 //byte[] serializedPrivateBytes = privateKeyInfo.ToAsn1Object().GetDerEncoded();
31                 //key.privateKey = Convert.ToBase64String(serializedPrivateBytes);//PEM秘钥
32 
33                 //SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pair.Public);
34                 //byte[] serializedPublicBytes = publicKeyInfo.ToAsn1Object().GetDerEncoded();
35                 //key.publicKey = Convert.ToBase64String(serializedPublicBytes);//PEM公钥 
36                 #endregion
37 
38                 return key;
39             }

 然后是将字符串转换为Pem密钥

  1             #region 解析
  2             private static RSAParameters CreateRsaFromPrivateKey(string privateKey)
  3             {
  4                 string tmp = privateKey.Replace("
", "").Replace("-----END RSA PRIVATE KEY-----", "").Replace("-----BEGIN RSA PRIVATE KEY-----", "");
  5                 var privateKeyBits = System.Convert.FromBase64String(tmp);
  6                 var RSAparams = new RSAParameters();
  7 
  8                 using (var binr = new BinaryReader(new MemoryStream(privateKeyBits)))
  9                 {
 10                     byte bt = 0;
 11                     ushort twobytes = 0;
 12                     twobytes = binr.ReadUInt16();
 13                     if (twobytes == 0x8130)
 14                         binr.ReadByte();
 15                     else if (twobytes == 0x8230)
 16                         binr.ReadInt16();
 17                     else
 18                         throw new Exception("Unexpected value read binr.ReadUInt16()");
 19 
 20                     twobytes = binr.ReadUInt16();
 21                     if (twobytes != 0x0102)
 22                         throw new Exception("Unexpected version");
 23 
 24                     bt = binr.ReadByte();
 25                     if (bt != 0x00)
 26                         throw new Exception("Unexpected value read binr.ReadByte()");
 27 
 28                     RSAparams.Modulus = binr.ReadBytes(GetIntegerSize(binr));
 29                     RSAparams.Exponent = binr.ReadBytes(GetIntegerSize(binr));
 30                     RSAparams.D = binr.ReadBytes(GetIntegerSize(binr));
 31                     RSAparams.P = binr.ReadBytes(GetIntegerSize(binr));
 32                     RSAparams.Q = binr.ReadBytes(GetIntegerSize(binr));
 33                     RSAparams.DP = binr.ReadBytes(GetIntegerSize(binr));
 34                     RSAparams.DQ = binr.ReadBytes(GetIntegerSize(binr));
 35                     RSAparams.InverseQ = binr.ReadBytes(GetIntegerSize(binr));
 36                 }
 37                 return RSAparams;
 38             }
 39 
 40             private static int GetIntegerSize(BinaryReader binr)
 41             {
 42                 byte bt = 0;
 43                 byte lowbyte = 0x00;
 44                 byte highbyte = 0x00;
 45                 int count = 0;
 46                 bt = binr.ReadByte();
 47                 if (bt != 0x02)
 48                     return 0;
 49                 bt = binr.ReadByte();
 50 
 51                 if (bt == 0x81)
 52                     count = binr.ReadByte();
 53                 else
 54                     if (bt == 0x82)
 55                 {
 56                     highbyte = binr.ReadByte();
 57                     lowbyte = binr.ReadByte();
 58                     byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
 59                     count = BitConverter.ToInt32(modint, 0);
 60                 }
 61                 else
 62                 {
 63                     count = bt;
 64                 }
 65 
 66                 while (binr.ReadByte() == 0x00)
 67                 {
 68                     count -= 1;
 69                 }
 70                 binr.BaseStream.Seek(-1, SeekOrigin.Current);
 71                 return count;
 72             }
 73 
 74             private static RSAParameters CreateRsaFromPublicKey(string publicKeyString)
 75             {
 76                 byte[] SeqOID = { 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00 };
 77                 byte[] x509key;
 78                 byte[] seq = new byte[15];
 79                 int x509size;
 80 
 81                 var tmp = publicKeyString.Replace("-----BEGIN PUBLIC KEY-----", "").Replace("-----END PUBLIC KEY-----", "").Replace("
", "");
 82 
 83                 x509key = Convert.FromBase64String(tmp);
 84                 x509size = x509key.Length;
 85 
 86                 using (var mem = new MemoryStream(x509key))
 87                 {
 88                     using (var binr = new BinaryReader(mem))
 89                     {
 90                         byte bt = 0;
 91                         ushort twobytes = 0;
 92 
 93                         twobytes = binr.ReadUInt16();
 94                         if (twobytes == 0x8130)
 95                             binr.ReadByte();
 96                         else if (twobytes == 0x8230)
 97                             binr.ReadInt16();
 98                         else
 99                             return new RSAParameters();
100 
101                         seq = binr.ReadBytes(15);
102                         if (!CompareBytearrays(seq, SeqOID))
103                             return new RSAParameters();
104 
105                         twobytes = binr.ReadUInt16();
106                         if (twobytes == 0x8103)
107                             binr.ReadByte();
108                         else if (twobytes == 0x8203)
109                             binr.ReadInt16();
110                         else
111                             return new RSAParameters();
112 
113                         bt = binr.ReadByte();
114                         if (bt != 0x00)
115                             return new RSAParameters();
116 
117                         twobytes = binr.ReadUInt16();
118                         if (twobytes == 0x8130)
119                             binr.ReadByte();
120                         else if (twobytes == 0x8230)
121                             binr.ReadInt16();
122                         else
123                             return new RSAParameters();
124 
125                         twobytes = binr.ReadUInt16();
126                         byte lowbyte = 0x00;
127                         byte highbyte = 0x00;
128 
129                         if (twobytes == 0x8102)
130                             lowbyte = binr.ReadByte();
131                         else if (twobytes == 0x8202)
132                         {
133                             highbyte = binr.ReadByte();
134                             lowbyte = binr.ReadByte();
135                         }
136                         else
137                             return new RSAParameters();
138                         byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
139                         int modsize = BitConverter.ToInt32(modint, 0);
140 
141                         int firstbyte = binr.PeekChar();
142                         if (firstbyte == 0x00)
143                         {
144                             binr.ReadByte();
145                             modsize -= 1;
146                         }
147 
148                         byte[] modulus = binr.ReadBytes(modsize);
149 
150                         if (binr.ReadByte() != 0x02)
151                             return new RSAParameters();
152                         int expbytes = (int)binr.ReadByte();
153                         byte[] exponent = binr.ReadBytes(expbytes);
154                         var rsaKeyInfo = new RSAParameters
155                         {
156                             Modulus = modulus,
157                             Exponent = exponent
158                         };
159                         return rsaKeyInfo;
160                     }
161 
162                 }
163             }
164 
165             private static bool CompareBytearrays(byte[] a, byte[] b)
166             {
167                 if (a.Length != b.Length)
168                     return false;
169                 int i = 0;
170                 foreach (byte c in a)
171                 {
172                     if (c != b[i])
173                         return false;
174                     i++;
175                 }
176                 return true;
177             } 
178             #endregion

C#后端加密解密方法

 1             //RSA加密
 2             public static string RSAEncrypt(string context, string publicKey)
 3             {
 4                 UTF8Encoding ByteConverter = new UTF8Encoding();
 5                 byte[] DataToEncrypt = ByteConverter.GetBytes(context);
 6                 try
 7                 {
 8                     var rsa = RSA.Create();
 9                     rsa.ImportParameters(CreateRsaFromPublicKey(publicKey));
10 
11                     byte[] bytes = rsa.Encrypt(DataToEncrypt, RSAEncryptionPadding.Pkcs1);
12                     string str = Convert.ToBase64String(bytes);
13                     return str;
14                 }
15                 catch (CryptographicException e)
16                 {
17                     throw e;
18                 }
19             }
20 
21             //RSA解密
22             public static string RSADecrypt(string context, string privateKey)
23             {
24                 byte[] DataToDecrypt = Convert.FromBase64String(context);
25                 try
26                 {
27                     var rsa = RSA.Create();
28                     rsa.ImportParameters(CreateRsaFromPrivateKey(privateKey));
29 
30                     byte[] bytes = rsa.Decrypt(DataToDecrypt, RSAEncryptionPadding.Pkcs1);
31                     UTF8Encoding ByteConverter = new UTF8Encoding();
32                     string str = ByteConverter.GetString(bytes);
33                     return str;
34                 }
35                 catch (CryptographicException e)
36                 {
37                     return null;
38                     throw e;
39                 }
40             }

ok以上就是后端代码。

前段代码就简单了,这个是jsencrypt官方的demo。

<!doctype html>
<html>
  <head>
    <title>JavaScript RSA Encryption</title>
    <script src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
    <script src="bin/jsencrypt.min.js"></script>
    <script type="text/javascript">

      // Call this code when the page is done loading.
      $(function() {

        // Run a quick encryption/decryption when they click.
        $('#testme').click(function() {

          // Encrypt with the public key...
          var encrypt = new JSEncrypt();
          encrypt.setPublicKey($('#pubkey').val());
          var encrypted = encrypt.encrypt($('#input').val());

          // Decrypt with the private key...
          var decrypt = new JSEncrypt();
          decrypt.setPrivateKey($('#privkey').val());
          var uncrypted = decrypt.decrypt(encrypted);

          // Now a simple check to see if the round-trip worked.
          if (uncrypted == $('#input').val()) {
            alert('It works!!!');
          }
          else {
            alert('Something went wrong....');
          }
        });
      });
    </script>
  </head>
  <body>
    <label for="privkey">Private Key</label><br/>
    <textarea id="privkey" rows="15" cols="65">-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDlOJu6TyygqxfWT7eLtGDwajtNFOb9I5XRb6khyfD1Yt3YiCgQ
WMNW649887VGJiGr/L5i2osbl8C9+WJTeucF+S76xFxdU6jE0NQ+Z+zEdhUTooNR
aY5nZiu5PgDB0ED/ZKBUSLKL7eibMxZtMlUDHjm4gwQco1KRMDSmXSMkDwIDAQAB
AoGAfY9LpnuWK5Bs50UVep5c93SJdUi82u7yMx4iHFMc/Z2hfenfYEzu+57fI4fv
xTQ//5DbzRR/XKb8ulNv6+CHyPF31xk7YOBfkGI8qjLoq06V+FyBfDSwL8KbLyeH
m7KUZnLNQbk8yGLzB3iYKkRHlmUanQGaNMIJziWOkN+N9dECQQD0ONYRNZeuM8zd
8XJTSdcIX4a3gy3GGCJxOzv16XHxD03GW6UNLmfPwenKu+cdrQeaqEixrCejXdAF
z/7+BSMpAkEA8EaSOeP5Xr3ZrbiKzi6TGMwHMvC7HdJxaBJbVRfApFrE0/mPwmP5
rN7QwjrMY+0+AbXcm8mRQyQ1+IGEembsdwJBAN6az8Rv7QnD/YBvi52POIlRSSIM
V7SwWvSK4WSMnGb1ZBbhgdg57DXaspcwHsFV7hByQ5BvMtIduHcT14ECfcECQATe
aTgjFnqE/lQ22Rk0eGaYO80cc643BXVGafNfd9fcvwBMnk0iGX0XRsOozVt5Azil
psLBYuApa66NcVHJpCECQQDTjI2AQhFc1yRnCU/YgDnSpJVm1nASoRUnU8Jfm3Oz
uku7JUXcVpt08DFSceCEX9unCuMcT72rAQlLpdZir876
-----END RSA PRIVATE KEY-----</textarea><br/>
    <label for="pubkey">Public Key</label><br/>
    <textarea id="pubkey" rows="15" cols="65">-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDlOJu6TyygqxfWT7eLtGDwajtN
FOb9I5XRb6khyfD1Yt3YiCgQWMNW649887VGJiGr/L5i2osbl8C9+WJTeucF+S76
xFxdU6jE0NQ+Z+zEdhUTooNRaY5nZiu5PgDB0ED/ZKBUSLKL7eibMxZtMlUDHjm4
gwQco1KRMDSmXSMkDwIDAQAB
-----END PUBLIC KEY-----</textarea><br/>
    <label for="input">Text to encrypt:</label><br/>
    <textarea id="input" name="input" type="text" rows=4 cols=70>This is a test!</textarea><br/>
    <input id="testme" type="button" value="Test Me!!!" /><br/>
  </body>
</html>

打完,收功,希望能给大家带来一点用处^_^

原文地址:https://www.cnblogs.com/FlyStupidBird/p/8309465.html