详解c#与js的rsa加密互通

ASN.1

抽象语法表示(标记)ASN.1(Abstract Syntax Notation One )一种数据定义语言,描述了对数据进行表示、编码、传输和解码的数据格式。网络管理系统中的管理信息库(MIB)、应用程序的数据结构、协议数据单元(PDU)都是用ASN.1定义的。

可以理解为ASN.1是对密钥结构定义的一种规范

密钥结构类型

PKCS#1

RSAPublicKey ::= SEQUENCE {
  modulus      INTEGER, -- n
  publicExponent  INTEGER  -- e
}

RSAPrivateKey ::= SEQUENCE {
 version      Version,
 modulus      INTEGER, -- n
 publicExponent  INTEGER, -- e
 privateExponent  INTEGER, -- d
 prime1      INTEGER, -- p
 prime2      INTEGER, -- q
 exponent1     INTEGER, -- d mod (p-1)
 exponent2     INTEGER, -- d mod (q-1)
 coefficient    INTEGER, -- (inverse of q) mod p
 otherPrimeInfos  OtherPrimeInfos OPTIONAL
}

PKCS#8

PublicKeyInfo ::= SEQUENCE {
 algorithm    AlgorithmIdentifier,
 PublicKey    BIT STRING ; 其中的BIT STRING是某个算法自己指定的二进制格式
               ; RSA算法的话,就是上面的RSAPublicKey
}

AlgorithmIdentifier ::= SEQUENCE {
 algorithm    OBJECT IDENTIFIER,
 parameters   ANY DEFINED BY algorithm OPTIONAL
}

PrivateKeyInfo ::= SEQUENCE {
 version     Version,
 algorithm    AlgorithmIdentifier,
 PrivateKey   BIT STRING
}

AlgorithmIdentifier ::= SEQUENCE {
 algorithm    OBJECT IDENTIFIER,
 parameters   ANY DEFINED BY algorithm OPTIONAL
}

密钥编码类型

der格式

二进制格式

pem格式

把der格式的数据用base64编码后,然后再在头尾加上一段“-----”开始的标记

证书类型

X.509证书

X.509只包含公钥,没有私钥,这种证书一般公开发布,可用于放在客服端使用,用于加密、验签

PKCS#12证书

因为X.509证书只包含公钥,但有些时候我们需要把私钥和公钥合并成一个证书,放在服务端使用,用于解密、签名。

PKCS#12就定义了这样一种证书,它既包含了公钥有包含了私钥。典型的入pfx、p12证书就是PKCS#12证书。

PKCS#7证书

当你收到一个网站的证书后,你需要验证其真实性。因为一个X.509证书包含了公钥、持有人信息、签名。为了验证其真实性,你需要签证其签名,而验证签名则需要签发的CA机构的公钥证书。同样原理,当你拿到CA机构的公钥证书后,你也需要验证该CA机构的真实性,而验证该CA机构的证书,你需要该CA上级机构的CA公钥证书...以此类推,你需要一直验证到根证书为止。所以为了验证一个网站证书的真实性,你需要的不仅一张证书,而是一个证书链。而PKCS#7就定义了这样一个证书链的类型结构。典型如p7b后缀名的证书就是这样的格式。

证书后缀

.cer/.crt:存放公钥,没有私钥,就是一个X.509证书,二进制形式存放

.pfx/.p12:存放公钥和私钥,通常包含保护密码,二进制方式

证书与密钥关系

数字证书和私钥是匹配的关系。就好比钥匙牌和钥匙的关系。在数字证书签发的时候,数字证书签发系统(CA系统),在生成数字证书的同时,还会随机生成一对密钥,一个私钥,一个公钥。数字证书标示用户身份, 相匹配的私钥和公钥,则是用来保障用户身份的可认证性。就好比咱们拿着一串钥匙,每个钥匙上都标明有时某某房间的钥匙,但是否是真的,还需要看能不能打开相应的房门。

密钥生成

/// <summary>
    /// 取得私钥和公钥 XML 格式,返回数组第一个是私钥,第二个是公钥.
    /// </summary>
    /// <param name="size">密钥长度,默认1024,可以为2048</param>
    /// <returns></returns>
    public static string[] CreateXmlKey(int size = 1024)
    {
      //密钥格式要生成pkcs#1格式的 而不是pkcs#8格式的
      RSACryptoServiceProvider sp = new RSACryptoServiceProvider(size);
      string privateKey = sp.ToXmlString(true);//private key
      string publicKey = sp.ToXmlString(false);//public key
      return new string[] { privateKey, publicKey };
    }

    /// <summary>
    /// 取得私钥和公钥 CspBlob 格式,返回数组第一个是私钥,第二个是公钥.
    /// </summary>
    /// <param name="size"></param>
    /// <returns></returns>
    public static string[] CreateCspBlobKey(int size = 1024)
    {
      //密钥格式要生成pkcs#1格式的 而不是pkcs#8格式的
      RSACryptoServiceProvider sp = new RSACryptoServiceProvider(size);
      string privateKey = System.Convert.ToBase64String(sp.ExportCspBlob(true));//private key
      string publicKey = System.Convert.ToBase64String(sp.ExportCspBlob(false));//public key 

      return new string[] { privateKey, publicKey };
    }
    /// <summary>
    /// 导出PEM PKCS#1格式密钥对,返回数组第一个是私钥,第二个是公钥.
    /// </summary>
    public static string[] CreateKey_PEM_PKCS1(int size = 1024)
    {
      RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(size);
      string privateKey = RSA_PEM.ToPEM(rsa, false, false);
      string publicKey = RSA_PEM.ToPEM(rsa, true, false);
      return new string[] { privateKey, publicKey };
    }

    /// <summary>
    /// 导出PEM PKCS#8格式密钥对,返回数组第一个是私钥,第二个是公钥.
    /// </summary>
    public static string[] CreateKey_PEM_PKCS8(int size = 1024, bool convertToPublic = false)
    {
      RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(size);
      string privateKey = RSA_PEM.ToPEM(rsa, false, true);
      string publicKey = RSA_PEM.ToPEM(rsa, true, true);
      return new string[] { privateKey, publicKey };

    }

后端加/解密方法使用

/// <summary>
    /// RSA加密
    /// </summary>
    /// <param name="Data">原文</param>
    /// <param name="PublicKeyString">公钥</param>
    /// <param name="KeyType">密钥类型XML/PEM</param>
    /// <returns></returns>
    public static string RSAEncrypt(string Data,string PublicKeyString,string KeyType)
    {
      byte[] data = Encoding.GetEncoding("UTF-8").GetBytes(Data);
      RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
      switch (KeyType)
      {
        case "XML":
          rsa.FromXmlString(PublicKeyString);
          break;
        case "PEM":
          rsa = RSA_PEM.FromPEM(PublicKeyString);
          break;
        default:
          throw new Exception("不支持的密钥类型");
      }
      //加密块最大长度限制,如果加密数据的长度超过 秘钥长度/8-11,会引发长度不正确的异常,所以进行数据的分块加密
      int MaxBlockSize = rsa.KeySize / 8 - 11;
      //正常长度
      if (data.Length <= MaxBlockSize)
      {
        byte[] hashvalueEcy = rsa.Encrypt(data, false); //加密
        return System.Convert.ToBase64String(hashvalueEcy);
      }
      //长度超过正常值
      else
      {
        using (MemoryStream PlaiStream = new MemoryStream(data))
        using (MemoryStream CrypStream = new MemoryStream())
        {
          Byte[] Buffer = new Byte[MaxBlockSize];
          int BlockSize = PlaiStream.Read(Buffer, 0, MaxBlockSize);
          while (BlockSize > 0)
          {
            Byte[] ToEncrypt = new Byte[BlockSize];
            Array.Copy(Buffer, 0, ToEncrypt, 0, BlockSize);

            Byte[] Cryptograph = rsa.Encrypt(ToEncrypt, false);
            CrypStream.Write(Cryptograph, 0, Cryptograph.Length);
            BlockSize = PlaiStream.Read(Buffer, 0, MaxBlockSize);
          }
          return System.Convert.ToBase64String(CrypStream.ToArray(), Base64FormattingOptions.None);
        }
      }
    }

    /// <summary>
    /// RSA解密
    /// </summary>
    /// <param name="Data">密文</param>
    /// <param name="PrivateKeyString">私钥</param>
    /// <param name="KeyType">密钥类型XML/PEM</param>
    /// <returns></returns>
    public static string RSADecrypt(string Data,string PrivateKeyString, string KeyType)
    {
      RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
      switch (KeyType)
      {
        case "XML":
          rsa.FromXmlString(PrivateKeyString);
          break;
        case "PEM":
          rsa = RSA_PEM.FromPEM(PrivateKeyString);
          break;
        default:
          throw new Exception("不支持的密钥类型");
      }
      int MaxBlockSize = rsa.KeySize / 8;  //解密块最大长度限制
      //正常解密
      if (Data.Length <= MaxBlockSize)
      {
        byte[] hashvalueDcy = rsa.Decrypt(System.Convert.FromBase64String(Data), false);//解密
        return Encoding.GetEncoding("UTF-8").GetString(hashvalueDcy);
      }
      //分段解密
      else
      {
        using (MemoryStream CrypStream = new MemoryStream(System.Convert.FromBase64String(Data)))
        using (MemoryStream PlaiStream = new MemoryStream())
        {
          Byte[] Buffer = new Byte[MaxBlockSize];
          int BlockSize = CrypStream.Read(Buffer, 0, MaxBlockSize);

          while (BlockSize > 0)
          {
            Byte[] ToDecrypt = new Byte[BlockSize];
            Array.Copy(Buffer, 0, ToDecrypt, 0, BlockSize);

            Byte[] Plaintext = rsa.Decrypt(ToDecrypt, false);
            PlaiStream.Write(Plaintext, 0, Plaintext.Length);
            BlockSize = CrypStream.Read(Buffer, 0, MaxBlockSize);
          }
          string output = Encoding.GetEncoding("UTF-8").GetString(PlaiStream.ToArray());
          return output;
        }
      }
    }

前端加密方法

注:jsencrypt默认PKCS#1结构,生成密钥时需要注意

<script src="http://passport.cnblogs.com/scripts/jsencrypt.min.js"></script>
 var encryptor = new JSEncrypt() // 创建加密对象实例
 //之前ssl生成的公钥,复制的时候要小心不要有空格
 var pubKey = '-----BEGIN PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC1QQRl0HlrVv6kGqhgonD6A9SU6ZJpnEN+Q0blT/ue6Ndt97WRfxtS'+
 'As0QoquTreaDtfC4RRX4o+CU6BTuHLUm+eSvxZS9TzbwoYZq7ObbQAZAY+SYDgAA5PHf1wNN20dGMFFgVS/y0ZWvv1UNa2laEz0I8Vmr5ZlzIn88GkmSiQIDAQAB-----END PUBLIC KEY-----'
 encryptor.setPublicKey(pubKey)//设置公钥
 var rsaPassWord = encryptor.encrypt('要加密的内容') // 对内容进行加密

c#pem格式转换

注:c#的RSACryptoServiceProvider默认只支持xml格式的密钥解析

public class RSA_Unit
  {
    static public string Base64EncodeBytes(byte[] byts)
    {
      return System.Convert.ToBase64String(byts);
    }
    static public byte[] Base64DecodeBytes(string str)
    {
      try
      {
        return System.Convert.FromBase64String(str);
      }
      catch
      {
        return null;
      }
    }
    /// <summary>
    /// 把字符串按每行多少个字断行
    /// </summary>
    static public string TextBreak(string text, int line)
    {
      var idx = 0;
      var len = text.Length;
      var str = new StringBuilder();
      while (idx < len)
      {
        if (idx > 0)
        {
          str.Append('\n');
        }
        if (idx + line >= len)
        {
          str.Append(text.Substring(idx));
        }
        else
        {
          str.Append(text.Substring(idx, line));
        }
        idx += line;
      }
      return str.ToString();
    }

  }
  static public class Extensions
  {
    /// <summary>
    /// 从数组start开始到指定长度复制一份
    /// </summary>
    static public T[] sub<T>(this T[] arr, int start, int count)
    {
      T[] val = new T[count];
      for (var i = 0; i < count; i++)
      {
        val[i] = arr[start + i];
      }
      return val;
    }
    static public void writeAll(this Stream stream, byte[] byts)
    {
      stream.Write(byts, 0, byts.Length);
    }
  }
点击并拖拽以移动
 public class RSA_PEM
  {
    public static RSACryptoServiceProvider FromPEM(string pem)
    {
      var rsaParams = new CspParameters();
      rsaParams.Flags = CspProviderFlags.UseMachineKeyStore;
      var rsa = new RSACryptoServiceProvider(rsaParams);

      var param = new RSAParameters();

      var base64 = _PEMCode.Replace(pem, "");
      var data = RSA_Unit.Base64DecodeBytes(base64);
      if (data == null)
      {
        throw new Exception("PEM内容无效");
      }
      var idx = 0;

      //读取长度
      Func<byte, int> readLen = (first) =>
      {
        if (data[idx] == first)
        {
          idx++;
          if (data[idx] == 0x81)
          {
            idx++;
            return data[idx++];
          }
          else if (data[idx] == 0x82)
          {
            idx++;
            return (((int)data[idx++]) << 8) + data[idx++];
          }
          else if (data[idx] < 0x80)
          {
            return data[idx++];
          }
        }
        throw new Exception("PEM未能提取到数据");
      };
      //读取块数据
      Func<byte[]> readBlock = () =>
      {
        var len = readLen(0x02);
        if (data[idx] == 0x00)
        {
          idx++;
          len--;
        }
        var val = data.sub(idx, len);
        idx += len;
        return val;
      };
      //比较data从idx位置开始是否是byts内容
      Func<byte[], bool> eq = (byts) =>
      {
        for (var i = 0; i < byts.Length; i++, idx++)
        {
          if (idx >= data.Length)
          {
            return false;
          }
          if (byts[i] != data[idx])
          {
            return false;
          }
        }
        return true;
      };

      if (pem.Contains("PUBLIC KEY"))
      {
        /****使用公钥****/
        //读取数据总长度
        readLen(0x30);
        if (!eq(_SeqOID))
        {
          throw new Exception("PEM未知格式");
        }
        //读取1长度
        readLen(0x03);
        idx++;//跳过0x00
           //读取2长度
        readLen(0x30);

        //Modulus
        param.Modulus = readBlock();

        //Exponent
        param.Exponent = readBlock();
      }
      else if (pem.Contains("PRIVATE KEY"))
      {
        /****使用私钥****/
        //读取数据总长度
        readLen(0x30);

        //读取版本号
        if (!eq(_Ver))
        {
          throw new Exception("PEM未知版本");
        }

        //检测PKCS8
        var idx2 = idx;
        if (eq(_SeqOID))
        {
          //读取1长度
          readLen(0x04);
          //读取2长度
          readLen(0x30);

          //读取版本号
          if (!eq(_Ver))
          {
            throw new Exception("PEM版本无效");
          }
        }
        else
        {
          idx = idx2;
        }

        //读取数据
        param.Modulus = readBlock();
        param.Exponent = readBlock();
        param.D = readBlock();
        param.P = readBlock();
        param.Q = readBlock();
        param.DP = readBlock();
        param.DQ = readBlock();
        param.InverseQ = readBlock();
      }
      else
      {
        throw new Exception("pem需要BEGIN END标头");
      }

      rsa.ImportParameters(param);
      return rsa;
    }
    static private Regex _PEMCode = new Regex(@"--+.+?--+|\s+");
    static private byte[] _SeqOID = new byte[] { 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00 };
    static private byte[] _Ver = new byte[] { 0x02, 0x01, 0x00 };

    /// <summary>
    /// 将RSA中的密钥对转换成PEM格式,usePKCS8=false时返回PKCS#1格式,否则返回PKCS#8格式,如果convertToPublic含私钥的RSA将只返回公钥,仅含公钥的RSA不受影响
    /// </summary>
    public static string ToPEM(RSACryptoServiceProvider rsa, bool convertToPublic, bool usePKCS8)
    {
      //https://www.jianshu.com/p/25803dd9527d
      //https://www.cnblogs.com/ylz8401/p/8443819.html
      //https://blog.csdn.net/jiayanhui2877/article/details/47187077
      //https://blog.csdn.net/xuanshao_/article/details/51679824
      //https://blog.csdn.net/xuanshao_/article/details/51672547

      var ms = new MemoryStream();
      //写入一个长度字节码
      Action<int> writeLenByte = (len) =>
      {
        if (len < 0x80)
        {
          ms.WriteByte((byte)len);
        }
        else if (len <= 0xff)
        {
          ms.WriteByte(0x81);
          ms.WriteByte((byte)len);
        }
        else
        {
          ms.WriteByte(0x82);
          ms.WriteByte((byte)(len >> 8 & 0xff));
          ms.WriteByte((byte)(len & 0xff));
        }
      };
      //写入一块数据
      Action<byte[]> writeBlock = (byts) =>
      {
        var addZero = (byts[0] >> 4) >= 0x8;
        ms.WriteByte(0x02);
        var len = byts.Length + (addZero ? 1 : 0);
        writeLenByte(len);

        if (addZero)
        {
          ms.WriteByte(0x00);
        }
        ms.Write(byts, 0, byts.Length);
      };
      //根据后续内容长度写入长度数据
      Func<int, byte[], byte[]> writeLen = (index, byts) =>
      {
        var len = byts.Length - index;

        ms.SetLength(0);
        ms.Write(byts, 0, index);
        writeLenByte(len);
        ms.Write(byts, index, len);

        return ms.ToArray();
      };

      if (rsa.PublicOnly || convertToPublic)
      {
        /****生成公钥****/
        var param = rsa.ExportParameters(false);

        //写入总字节数,不含本段长度,额外需要24字节的头,后续计算好填入
        ms.WriteByte(0x30);
        var index1 = (int)ms.Length;

        //固定内容
        // encoded OID sequence for PKCS #1 rsaEncryption szOID_RSA_RSA = "1.2.840.113549.1.1.1"
        ms.writeAll(_SeqOID);

        //从0x00开始的后续长度
        ms.WriteByte(0x03);
        var index2 = (int)ms.Length;
        ms.WriteByte(0x00);

        //后续内容长度
        ms.WriteByte(0x30);
        var index3 = (int)ms.Length;

        //写入Modulus
        writeBlock(param.Modulus);

        //写入Exponent
        writeBlock(param.Exponent);

        //计算空缺的长度
        var byts = ms.ToArray();

        byts = writeLen(index3, byts);
        byts = writeLen(index2, byts);
        byts = writeLen(index1, byts);

        return "-----BEGIN PUBLIC KEY-----\n" + RSA_Unit.TextBreak(RSA_Unit.Base64EncodeBytes(byts), 64) + "\n-----END PUBLIC KEY-----";
      }
      else
      {
        /****生成私钥****/
        var param = rsa.ExportParameters(true);

        //写入总字节数,后续写入
        ms.WriteByte(0x30);
        int index1 = (int)ms.Length;

        //写入版本号
        ms.writeAll(_Ver);

        //PKCS8 多一段数据
        int index2 = -1, index3 = -1;
        if (usePKCS8)
        {
          //固定内容
          ms.writeAll(_SeqOID);

          //后续内容长度
          ms.WriteByte(0x04);
          index2 = (int)ms.Length;

          //后续内容长度
          ms.WriteByte(0x30);
          index3 = (int)ms.Length;

          //写入版本号
          ms.writeAll(_Ver);
        }

        //写入数据
        writeBlock(param.Modulus);
        writeBlock(param.Exponent);
        writeBlock(param.D);
        writeBlock(param.P);
        writeBlock(param.Q);
        writeBlock(param.DP);
        writeBlock(param.DQ);
        writeBlock(param.InverseQ);

        //计算空缺的长度
        var byts = ms.ToArray();

        if (index2 != -1)
        {
          byts = writeLen(index3, byts);
          byts = writeLen(index2, byts);
        }
        byts = writeLen(index1, byts);

        var flag = " PRIVATE KEY";
        if (!usePKCS8)
        {
          flag = " RSA" + flag;
        }
        return "-----BEGIN" + flag + "-----\n" + RSA_Unit.TextBreak(RSA_Unit.Base64EncodeBytes(byts), 64) + "\n-----END" + flag + "-----";
      }
    }
  }

以上就是详解c#与js的rsa加密互通的详细内容,更多关于c#与js的rsa加密互通的资料请关注我们其它相关文章!

(0)

相关推荐

  • C#使用RSA加密解密文件

    本文实例为大家分享了C#使用RSA加密解密文件的具体代码,供大家参考,具体内容如下 加密代码: //加密代码,注意会覆盖原文件,里面有我的公钥,你要用时记得覆盖我的公钥 private bool encryptFile(string filename) { FileStream f; try { f = new FileStream(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.Read); } catch { return f

  • c# RSA非对称加解密及XML&PEM格式互换方案

    最近因考虑接口安全问题,有实现给WEB API实现统一的参数鉴权功能,以防止请求参数被篡改或重复执行,参数鉴权方法基本与常见的鉴权思路相同,采用(timestamp+sign),而我为了防止timestamp被更改,sign算法(timestamp+相关参数排序.格式化后拼接再MD5)也因为在前端是不安全的,故对timestamp采取使用非对称加解密,以尽可能的保证生成的sign不易被破解或替换: RSA加解密(即:非对称加解密) 生成公钥.私钥对方法(C#),生成出来后默认都是XML格式: p

  • jQuery+C#实现参数RSA加密传输功能【附jsencrypt.js下载】

    本文实例讲述了jQuery+C#实现参数RSA加密传输功能.分享给大家供大家参考,具体如下: 注意: 参数传递的+号处理,在传输时会把+变成空格,不处理后端就报错了. 1.前端代码 <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Login</title> <

  • C#实现简单的RSA非对称加密算法示例

    本文实例讲述了C#实现简单的RSA非对称加密算法.分享给大家供大家参考,具体如下: 界面控件 namespace RSA算法 { partial class Form1 { /// <summary> /// 必需的设计器变量. /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// 清理所有正在使用的资源. /// </summary

  • 少见的C# RSA算法

    当下最流行的RSA加密算法,只有公钥和私钥同时拥有才能破解加密信息,RSA加密算法的出现有利于数据安全性传输 1.C#中自带RSACryptoServiceProvider类可以让你很好的生成XML格式的公钥和私钥,两句代码就搞定 2.但是生成的XML格式前端不能很好的利用和读懂,所以在生成的XML格式里需要转换成PEM格式,这样才能直接Copy到验证工具里加密解密,非常方便 首先,我们先导入一个第三方库,因为下面涉及到的转换代码都是需要依赖这个库来实现,导入操作如下 控制台里输入 PM > I

  • 同时兼容JS和C#的RSA加密解密算法详解(对web提交的数据加密传输)

    前言 我们在Web应用中往往涉及到敏感的数据,由于HTTP协议以明文的形式与服务器进行交互,因此可以通过截获请求的数据包进行分析来盗取有用的信息.虽然https可以对传输的数据进行加密,但是必须要申请证书(一般都是收费的),成本较高.那么问题来了,如果对web提交的敏感数据进行加密呢?web应用中,前端的数据处理和交互基本上都是靠javascript来完成,后台的逻辑处理可以C#(java)等进行处理. 微软的C#中虽然有RSA算法,但是格式和OpenSSL生成的公钥/私钥文件格式并不兼容.这个

  • c# rsa加密解密详解

    前言 RSA加密算法是一种非对称加密算法,简单来说,就是加密时使用一个钥匙,解密时使用另一个钥匙. 因为加密的钥匙是公开的,所又称公钥,解密的钥匙是不公开的,所以称为私钥. 密钥 关于RSA加密有很多文章,但几乎都只介绍了RSACryptoServiceProvider类的使用方法,如果只是走走看看,是没问题的,但真的想使用时,就会发现,你没有密钥字符串... 下面我们从获取密钥字符串开始逐步学习加密. 密钥字符串 每个安装过VisualStudio的电脑都可以找到一个文件-makecert.e

  • C#中RSA加密与解密的实例详解

    1.  RSA加密与解密  --  使用公钥加密.私钥解密 public class RSATool { public string Encrypt(string strText, string strPublicKey) { RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); rsa.FromXmlString(strPublicKey); byte[] byteText = Encoding.UTF8.GetBytes

  • C#RSA对接JAVA中RSA方式代码实例

    C#中通过FromXmlString属性加载的是XML形式,而JAVA中用到的是解析后的PEM格式的字符串,总之读取证书中信息无非是转换方式问题 /// <summary> /// c# 使用 java 的公钥进行rsa加密 utf8编码 通过解析公钥加密数据 /// </summary> /// <param name="publickey"></param> /// <returns></returns> pu

  • 详解c#与js的rsa加密互通

    ASN.1 抽象语法表示(标记)ASN.1(Abstract Syntax Notation One )一种数据定义语言,描述了对数据进行表示.编码.传输和解码的数据格式.网络管理系统中的管理信息库(MIB).应用程序的数据结构.协议数据单元(PDU)都是用ASN.1定义的. 可以理解为ASN.1是对密钥结构定义的一种规范 密钥结构类型 PKCS#1 RSAPublicKey ::= SEQUENCE { modulus INTEGER, -- n publicExponent INTEGER

  • Js参数RSA加密传输之jsencrypt.js的使用

    注意几点: 1.参数传递的+号处理,在传输时会把+变成空格,不处理后端就报错了. 1.前端代码 <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Login</title> <script src="~/Scripts/jquery-1.10.2.m

  • 详解在Vue.js编写更好的v-for循环的6种技巧

    在VueJS中,v-for循环是每个项目都会使用的东西,它允许您在模板代码中编写for循环. 在最基本的用法中,它们的用法如下. <ul> <li v-for='product in products'> {{ product.name }} </li> </ul> 但是,在本文中,我将介绍六种方法来使你的 v-for 代码更加精确,可预测和强大. 让我们开始吧. 1.始终在v-for循环中使用key 首先,我们将讨论大多数Vue开发人员已经知道的常见最佳做

  • 详解阿里Node.js技术文档之process模块学习指南

    模块概览 process是node的全局模块,作用比较直观.可以通过它来获得node进程相关的信息,比如运行node程序时的命令行参数.或者设置进程相关信息,比如设置环境变量. 环境变量:process.env 使用频率很高,node服务运行时,时常会判断当前服务运行的环境,如下所示 if(process.env.NODE_ENV === 'production'){ console.log('生产环境'); }else{ console.log('非生产环境'); } 运行命令 NODE_EN

  • 详解在node.js中require方法的加载规则

    require 方法的加载规则 优先从缓存中加载 核心模块 路径形式的模块 第三方模块 一.优先从缓存中加载 main.js:执行加载a.js模块 require('./a') a.js:执行加载b.js模块,并输出a被加载了 require('./b') console.log('a.js 被加载了') b.js:输出b被加载了 console.log('b.js 被加载了') 结果: 可以看出:main去加载a.js,然后a在去加载b.js过程中,并没有打印两次 a.js被加载,Node会直

  • 详解如何利用jasypt实现配置文件加密

    目录 引入依赖 生效 作用域 应用 工具类 配置 属性一览 进阶 Jasypt (Java Simplified Encryption) 是一个 java 库,它允许开发人员以最小的成本将基本的加密功能添加到项目中,而无需深入了解密码学的工作原理. 引入依赖 <dependency> <groupId>com.github.ulisesbocchio</groupId> <artifactId>jasypt-spring-boot-starter</a

  • 详解如何用js实现一个网页版节拍器

    目录 引言 1. 需求分析 2. 素材准备 3. 开发实现 3.1 框架选型 3.2 模块设计 3.3 数据结构设计 3.4 播放逻辑 3.5 音频控制 3.6 动效 3.7 大屏展示 3.8 新增人声发音 4. 部署 5. 后续工作 5.1 目前存在的问题 ios声音 5.2 TODO 切换不同音效 引言 平时练尤克里里经常用到节拍器,突发奇想自己用js开发一个. 最后实现的效果如下:ahao430.github.io/metronome/. 代码见github仓库:github.com/ah

  • 详解Android端与JavaWeb传输加密(DES+RSA)

    一.加密介绍 本文采用对称式加密算法DES和非对称式加密算法RSA结合做数据传输加密的方式. 先说一下对称式加密 DES:对称式加密即使用单钥密码加密的方法,信息的加密和解密使用同一个秘钥,这种方式也称为单秘钥加密.所谓对称就是指加密和解密使用的是同一个秘钥! 常用的对称加密有:DES.IDEA.RC2.RC4.SKIPJACK.RC5.AES算法等. 与对称加密算法不同,非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥 (privatekey).公开密钥与私有密钥是一对,如

  • 详解用Node.js写一个简单的命令行工具

    本文介绍了用Node.js写一个简单的命令行工具,分享给大家,具体如下: 操作系统需要为Linux 1. 目标 在命令行输入自己写的命令,完成目标任务 命令行要求全局有效 命令行要求可以删除 命令行作用,生成一个文件,显示当前的日期 2. 代码部分 新建一个文件,命名为sherryFile 文件sherryFile的内容 介绍: 生成一个文件,文件内容为当前日期和创建者 #! /usr/bin/env node console.log('command start'); const fs = r

  • 详解基于Node.js的微信JS-SDK后端接口实现代码

    做了一个网站,放到线上,用微信打开,点击分享,可是分享后发给朋友的链接卡片是微信默认自带的,如下: 这标题,描述以及图片是默认自带的,丑不说,分享给别人还以为是盗号网站呢,而接入微信的JSSDK后,分享可以自定义内容,如下: 我承认,虽然这分享的标题和内容也并不正经,但这不妨碍我表达我们可以通过微信JSSDK定义分享内容,接下来我们将一步一步从零实现JSSDK从后端Node.js的接入. 成为测试公众号开发者 登录测试公众号后台 首先我们需要在微信公众平台申请测试接口,地址:https://mp

随机推荐