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

收工!

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

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

 

posted @ 2021-08-19 10:37  Johnny Li  阅读(1350)  评论(0编辑  收藏  举报