• 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
Copyright © 2020-2023  润新知