本文主要讲述.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); }
收工!
如果本文对你有帮助,请点一下推荐就是对博主最大的支持!
转载请注明出处!不注明也只有你自已知道!