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);
        }

    收工!

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

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

  • 相关阅读:
    [你必须知道的.NET] 第四回:后来居上:class和struct
    [你必须知道的.NET]第十回:品味类型值类型与引用类型(下)-应用征途
    [你必须知道的.NET]第十一回:参数之惑传递的艺术(上)
    [你必须知道的.NET] 第一回:恩怨情仇:is和as
    [Anytao.History] 排名进入1000,未来值得努力
    [你必须知道的.NET] 第三回:历史纠葛:特性和属性
    [你必须知道的.NET] 第八回:品味类型值类型与引用类型(上)-内存有理
    [你必须知道的.NET] 第五回:深入浅出关键字把new说透
    [你必须知道的.NET]第十二回:参数之惑传递的艺术(下)
    .NET 3.5
  • 原文地址:https://www.cnblogs.com/lisweden/p/15160607.html
Copyright © 2011-2022 走看看