zoukankan      html  css  js  c++  java
  • .Net Core对接Java密钥,使用RS256算法实现加签、摘要、JWT验签

    本文主要讲述.Net Core对接Java密钥,使用RS256算法实现加签、摘要、验签,也是参考了网上的一些资料。

    首先,java平台下的公钥和私钥,均采用的是base64String格式,而.net 平台下的,使用的是xmlString格式。所以第一步要实现这两者之间的转换。

    我这里使用了一个常用的加密和解密的包:BouncyCastle.NetCore,github地址,大家可以去star一下,对.net core好的项目要支持和加油。

    dotnet add package BouncyCastle.NetCore

    1、.NetCore密钥与Java密钥间转换

        public static string PrivateKeyDotNet2Java(string dotNetXmlPrivateKey)
        {
          string result = string.Empty;
          using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
          {
            rsa.FromXmlString(dotNetXmlPrivateKey);
            RSAParameters p = rsa.ExportParameters(true);
            RsaPrivateCrtKeyParameters privateKeyParam = new RsaPrivateCrtKeyParameters(
                new BigInteger(1, p.Modulus), new BigInteger(1, p.Exponent),
                new BigInteger(1, p.D), new BigInteger(1, p.P),
                new BigInteger(1, p.Q), new BigInteger(1, p.DP),
                new BigInteger(1, p.DQ), new BigInteger(1, p.InverseQ)
            );
            PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKeyParam);
            result = Convert.ToBase64String(privateKeyInfo.ToAsn1Object().GetEncoded());
          }
          return result;
        }
    
        public static string PublicKeyDotNet2Java(string publicKey)
        {
          string result = string.Empty;
          using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
          {
            rsa.FromXmlString(publicKey);
            RSAParameters p = rsa.ExportParameters(false);
            BigInteger m = new BigInteger(1, p.Modulus);
            BigInteger exp = new BigInteger(1, p.Exponent);
    
            RsaKeyParameters pub = new RsaKeyParameters(false, m, exp);
    
            SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pub);
            byte[] seriaPublicKey = publicKeyInfo.ToAsn1Object().GetEncoded();
            result = Convert.ToBase64String(seriaPublicKey);
          }
          return result;
        }
    
        public static string ToXmlPrivateKey(string privateKey)
        {
          RsaPrivateCrtKeyParameters privateKeyParams = PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKey)) as RsaPrivateCrtKeyParameters;
          using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
          {
            RSAParameters rsaParams = new RSAParameters()
            {
              Modulus = privateKeyParams.Modulus.ToByteArrayUnsigned(),
              Exponent = privateKeyParams.PublicExponent.ToByteArrayUnsigned(),
              D = privateKeyParams.Exponent.ToByteArrayUnsigned(),
              DP = privateKeyParams.DP.ToByteArrayUnsigned(),
              DQ = privateKeyParams.DQ.ToByteArrayUnsigned(),
              P = privateKeyParams.P.ToByteArrayUnsigned(),
              Q = privateKeyParams.Q.ToByteArrayUnsigned(),
              InverseQ = privateKeyParams.QInv.ToByteArrayUnsigned()
            };
            rsa.ImportParameters(rsaParams);
            return rsa.ToXmlString(true);
          }
        }
    
        public static string ToXmlPublicKey(string publicKey)
        {
          RsaKeyParameters p = PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKey)) as RsaKeyParameters;
          using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
          {
            RSAParameters rsaParams = new RSAParameters()
            {
              Modulus = p.Modulus.ToByteArrayUnsigned(),
              Exponent = p.Exponent.ToByteArrayUnsigned()
            };
            rsa.ImportParameters(rsaParams);
            return rsa.ToXmlString(false);
          }
        }

    2、私钥签名

        public static string SignByPrivateKey(string data, string privateKey)
        {
          AsymmetricKeyParameter priKey = PublicKeyFactory.CreateKey(Convert.FromBase64String(privateKey));
          byte[] byteData = Encoding.UTF8.GetBytes(data);
    
          ISigner normalSign = SignerUtilities.GetSigner("SHA256WithRSA");
          normalSign.Init(true, priKey);
          normalSign.BlockUpdate(byteData, 0, byteData.Length);
          string signResult = Convert.ToBase64String(normalSign.GenerateSignature());
          return signResult;
        }

    3、SHA256生成摘要

        public static string GetSHA256Code(string data)
        {
          byte[] byteData = Encoding.UTF8.GetBytes(data);
    
          SHA256Managed sha256 = new SHA256Managed();
          byte[] sha256Data = sha256.ComputeHash(byteData);
          string result = Convert.ToBase64String(sha256Data);
    
          return result;
        }

    4、JWT Token 签名验证 //SHA256

        public static bool JWTStringVerifySign(string jwtToken, string pubKey, out string errMsg)
        {
          errMsg = string.Empty;
          try
          {
            string[] jwtArray = jwtToken.Split(',');
            string signature = jwtArray[2];
            byte[] data = Encoding.UTF8.GetBytes(string.Concat(jwtArray[0], ".", jwtArray[1]));
            string safeSignature = DecodeBase64SafeUrl(signature); //安全URL解码
            byte[] signatureData = Convert.FromBase64String(safeSignature);
    
            RsaKeyParameters p = PublicKeyFactory.CreateKey(Convert.FromBase64String(pubKey)) as RsaKeyParameters;
            using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
            {
              RSAParameters rsaParams = new RSAParameters()
              {
                Modulus = p.Modulus.ToByteArrayUnsigned(),
                Exponent = p.Exponent.ToByteArrayUnsigned()
              };
              rsa.ImportParameters(rsaParams);
              bool result = rsa.VerifyData(data, signatureData, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
              return result;
            }
          }
          catch (Exception ex)
          {
            errMsg = ex.Message + ex.StackTrace;
            return false;
          }
        }
    
        public static string DecodeBase64SafeUrl(string data)
        {
          data = data.Replace("-", "+").Replace("_", "/");
          int len = data.Length % 4;
          if (len > 0)
          {
            data += "====".Substring(0, 4 - len);
          }
          return data;
        }

    5、生成.Net Core密钥

        public static Tuple<string, string> CreateRsaPublicKey(int keySize = 2048)
        {
          RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(keySize);
          string privateKey = rsa.ToXmlString(true);
          string publicKey = rsa.ToXmlString(false);
    
          string javaPrivateKey = PrivateKeyDotNet2Java(privateKey);
          string javaPublicKey = PublicKeyDotNet2Java(publicKey);
    
          return new Tuple<string, string>(javaPublicKey, javaPrivateKey);
        }

    收工!

    如果本文对你有帮助,请点一下推荐就是对博主最大的支持!

    转载请注明出处!不注明也只有你自已知道!

  • 相关阅读:
    QT4.7.1 + VS2008 + QT Designer开发流程心得
    SharePoint 2010 托管元数据Bug (跟邮件提醒功能相关.小bug,大问题)
    SharePoint 2010 技巧系列: 控制Ribbon菜单权限(SiteActions的例子)
    发布一个SharePoint 2010 工具(复制,移动文件和文件夹)
    SHarePoint 2010 技巧 列验证 (column Validation)
    SharePoint 2010系列: 教你如何创建Internet 站点一 (设计母版页)
    SharePoint2010 技巧系列:快速开发Ribbon
    SharePoint 2010 技巧: 限制People Picker搜索非站点集内的用户
    SharePoint 2010 技巧系列 启用文档库接收邮件功能
    SharePoint 2010 技巧系列: 文档管理的自动分发功能
  • 原文地址:https://www.cnblogs.com/lisweden/p/15160607.html
Copyright © 2011-2022 走看看