C# Java RSA互通
Java代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 | package com.pkuhit.mobile.pay.alipay.api.sign; import com.founder.smc.util.Base64Util; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Security; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import javax.crypto.Cipher; public class RSA{ public static final String SIGN_ALGORITHMS = "SHA1WithRSA" ; /** * RSA签名 * @param content 待签名数据 * @param privateKey 商户私钥 * @param input_charset 编码格式 * @return 签名值 */ public static String sign(String content, String privateKey, String input_charset) { try { PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec( Base64.decode(privateKey) ); KeyFactory keyf = KeyFactory.getInstance( "RSA" ); PrivateKey priKey = keyf.generatePrivate(priPKCS8); java.security.Signature signature = java.security.Signature .getInstance(SIGN_ALGORITHMS); signature.initSign(priKey); signature.update( content.getBytes(input_charset) ); byte [] signed = signature.sign(); return Base64.encode(signed); } catch (Exception e) { e.printStackTrace(); } return null ; } /** * RSA验签名检查 * @param content 待签名数据 * @param sign 签名值 * @param ali_public_key 支付宝公钥 * @param input_charset 编码格式 * @return 布尔值 */ public static boolean verify(String content, String sign, String ali_public_key, String input_charset) { try { KeyFactory keyFactory = KeyFactory.getInstance( "RSA" ); byte [] encodedKey = Base64.decode(ali_public_key); PublicKey pubKey = keyFactory.generatePublic( new X509EncodedKeySpec(encodedKey)); java.security.Signature signature = java.security.Signature .getInstance(SIGN_ALGORITHMS); signature.initVerify(pubKey); signature.update( content.getBytes(input_charset) ); boolean bverify = signature.verify( Base64.decode(sign) ); return bverify; } catch (Exception e) { e.printStackTrace(); } return false ; } /** * 解密 * @param content 密文 * @param private_key 商户私钥 * @param input_charset 编码格式 * @return 解密后的字符串 */ public static String decrypt(String content, String private_key, String input_charset) throws Exception { PrivateKey prikey = getPrivateKey(private_key); Cipher cipher = Cipher.getInstance( "RSA" ); cipher.init(Cipher.DECRYPT_MODE, prikey); InputStream ins = new ByteArrayInputStream(Base64.decode(content)); ByteArrayOutputStream writer = new ByteArrayOutputStream(); //rsa解密的字节大小最多是128,将需要解密的内容,按128位拆开解密 byte [] buf = new byte [ 128 ]; int bufl; while ((bufl = ins.read(buf)) != - 1 ) { byte [] block = null ; if (buf.length == bufl) { block = buf; } else { block = new byte [bufl]; for ( int i = 0 ; i < bufl; i++) { block[i] = buf[i]; } } writer.write(cipher.doFinal(block)); } return new String(writer.toByteArray(), input_charset); } /** * 得到私钥 * @param key 密钥字符串(经过base64编码) * @throws Exception */ public static PrivateKey getPrivateKey(String key) throws Exception { byte [] keyBytes; keyBytes = Base64.decode(key); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance( "RSA" ); PrivateKey privateKey = keyFactory.generatePrivate(keySpec); return privateKey; } /** *加密 * @param content 明文 * @param public_key 公钥 * @param input_charset 编码格式(UTF-8) * @return 加密后的字符串 * @throws Exception */ public static String encrypt(String content,String public_key, String input_charset) throws Exception { PublicKey publicKey = getPublicKey(public_key); Security.addProvider( new org.bouncycastle.jce.provider.BouncyCastleProvider()); Cipher cipher = Cipher.getInstance( "RSA" ); cipher.init(Cipher.ENCRYPT_MODE,publicKey); ByteArrayOutputStream writer = new ByteArrayOutputStream(); //加密最大长度为117b(密钥长度为1024时),超过该长度的进行分块处理 byte [] encryptData = null ; byte [] con = content.getBytes( "UTF-8" ); byte [] cache; int offSet = 0 ,i= 0 ; int dataLength = con.length; while (dataLength - offSet > 0 ){ if (dataLength - offSet > 117 ){ cache = cipher.doFinal(con,offSet, 117 ); } else { cache = cipher.doFinal(con,offSet,dataLength-offSet); } writer.write(cache, 0 ,cache.length); i++; offSet = i* 117 ; } encryptData = writer.toByteArray(); writer.close(); //先用RSA加密再用base64加密 return Base64Util.encode(encryptData); } /** * 公钥字符串转PublicKey实例 * @param publicKey * @return * @throws Exception */ public static PublicKey getPublicKey(String publicKey) throws Exception { byte [] publicKeyBytes = Base64Util.decode(publicKey); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes); KeyFactory keyFactory = KeyFactory.getInstance( "RSA" ); return keyFactory.generatePublic(keySpec); } public static void main(String[] args) throws Exception { String clientPrivateKey= "" ; String clientPublicKey= "" ; String context = "老铁" ; String encryptData = encrypt(context,clientPublicKey, "UTF-8" ); System.out.println( "encryptData=>" +encryptData); String decryptData = decrypt(encryptData,clientPrivateKey, "UTF-8" ); System.out.println( "decryptData=>" +decryptData); } } |
C# 代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | public partial class RSAHelper { #region 私钥加密 /// <summary> /// 基于Portable.BouncyCastle的RSA私钥加密 /// </summary> /// <param name="privateKeyJava"></param> /// <param name="data"></param> /// <returns></returns> public static string EncryptPrivateKeyJava( string privateKeyJava, string data, string encoding = "UTF-8" ) { RsaKeyParameters privateKeyParam = (RsaKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKeyJava)); byte [] cipherbytes = Encoding.GetEncoding(encoding).GetBytes(data); RsaEngine rsa = new RsaEngine(); rsa.Init( true , privateKeyParam); //参数true表示加密/false表示解密。 cipherbytes = rsa.ProcessBlock(cipherbytes, 0, cipherbytes.Length); return Convert.ToBase64String(cipherbytes); } #endregion #region 公钥解密 /// <summary> /// 基于Portable.BouncyCastle的RSA公钥解密 /// </summary> /// <param name="publicKeyJava"></param> /// <param name="data"></param> /// <param name="encoding"></param> /// <returns></returns> public static string DecryptPublicKeyJava( string publicKeyJava, string data, string encoding = "UTF-8" ) { RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKeyJava)); byte [] cipherbytes = Convert.FromBase64String(data); RsaEngine rsa = new RsaEngine(); rsa.Init( false , publicKeyParam); //参数true表示加密/false表示解密。 cipherbytes = rsa.ProcessBlock(cipherbytes, 0, cipherbytes.Length); return Encoding.GetEncoding(encoding).GetString(cipherbytes); } #endregion #region 加签 /// <summary> /// 基于Portable.BouncyCastle的RSA签名 /// </summary> /// <param name="data"></param> /// <param name="privateKeyJava"></param> /// <param name="hashAlgorithm">JAVA的和.NET的不一样,如:MD5(.NET)等同于MD5withRSA(JAVA)</param> /// <param name="encoding"></param> /// <returns></returns> public static string RSASignJavaBouncyCastle( string data, string privateKeyJava, string hashAlgorithm = "SHA1WITHRSA" , string encoding = "UTF-8" ) { RsaKeyParameters privateKeyParam = (RsaKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKeyJava)); ISigner signer = SignerUtilities.GetSigner(hashAlgorithm); signer.Init( true , privateKeyParam); //参数为true验签,参数为false加签 var dataByte = Encoding.GetEncoding(encoding).GetBytes(data); signer.BlockUpdate(dataByte, 0, dataByte.Length); //return Encoding.GetEncoding(encoding).GetString(signer.GenerateSignature()); //签名结果 非Base64String return Convert.ToBase64String(signer.GenerateSignature()); } #endregion #region 验签 /// <summary> /// 基于Portable.BouncyCastle的RSA签名 /// </summary> /// <param name="data">源数据</param> /// <param name="publicKeyJava"></param> /// <param name="signature">base64签名</param> /// <param name="hashAlgorithm">JAVA的和.NET的不一样,如:MD5(.NET)等同于MD5withRSA(JAVA)</param> /// <param name="encoding"></param> /// <returns></returns> public static bool VerifyJavaBouncyCastle( string data, string publicKeyJava, string signature, string hashAlgorithm = "SHA1WITHRSA" , string encoding = "UTF-8" ) { RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKeyJava)); ISigner signer = SignerUtilities.GetSigner(hashAlgorithm); signer.Init( false , publicKeyParam); byte [] dataByte = Encoding.GetEncoding(encoding).GetBytes(data); signer.BlockUpdate(dataByte, 0, dataByte.Length); //byte[] signatureByte = Encoding.GetEncoding(encoding).GetBytes(signature);// 非Base64String byte [] signatureByte = Convert.FromBase64String(signature); return signer.VerifySignature(signatureByte); } #endregion /// <summary> /// RSA公钥加密 /// </summary> /// <param name="data"></param> /// <returns></returns> private static string RSAEncrypt( string data) { using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider()) { rsa.FromXmlString(RSAPublicKeyJava2DotNet(PublicKey)); byte [] cipherbytes = rsa.Encrypt(Encoding.UTF8.GetBytes(data), RSAEncryptionPadding.OaepSHA1); return Convert.ToBase64String(cipherbytes); } } /// <summary> /// RSA私钥解密 /// </summary> /// <param name="data"></param> /// <returns></returns> private static string RSADecrypt( string data) { using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider()) { rsa.FromXmlString(RSAPrivateKeyJava2DotNet(PrivateKey)); byte [] cipherbytes = rsa.Decrypt(Convert.FromBase64String(data), RSAEncryptionPadding.OaepSHA1); return Encoding.UTF8.GetString(cipherbytes); } } /// <summary> /// RSA公钥格式转换,java->.net /// </summary> /// <param name="publicKey">java生成的公钥</param> /// <returns></returns> private static string RSAPublicKeyJava2DotNet( string publicKey) { RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKey)); return string .Format( "<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent></RSAKeyValue>" , Convert.ToBase64String(publicKeyParam.Modulus.ToByteArrayUnsigned()), Convert.ToBase64String(publicKeyParam.Exponent.ToByteArrayUnsigned())); } /// <summary> /// RSA私钥格式转换,java->.net /// </summary> /// <param name="privateKey">java生成的RSA私钥</param> /// <returns></returns> public static string RSAPrivateKeyJava2DotNet( string privateKey) { RsaPrivateCrtKeyParameters privateKeyParam = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKey)); return string .Format( "<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent><P>{2}</P><Q>{3}</Q><DP>{4}</DP><DQ>{5}</DQ><InverseQ>{6}</InverseQ><D>{7}</D></RSAKeyValue>" , Convert.ToBase64String(privateKeyParam.Modulus.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.PublicExponent.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.P.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.Q.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.DP.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.DQ.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.QInv.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.Exponent.ToByteArrayUnsigned())); } #region 登录密钥 /* * 密钥对生成地址:http://web.chacuo.net/netrsakeypair 位数:2048 密钥格式:PKCS#8 输出格式:PEM/Base64 */ private static readonly string PublicKey = @"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0/ViBSWEZQv6N3wGqNoW Dw6hw1e+iFyrg2aoL7sFb67KEx6qJuWFQEwSjtv+aprEGmR3q35U9t0Z3dQzstSf 0nZ9Xq4GqDsq4bhBiBDhoKXJf0G4d4R7LeHXb95Z3Cu1IGtpATiC1nu/k5LbvSks WaqpNPTqW0E6stUqijYq/dloAXGcyW1j5zWlK92RXTtEi/Rh35VqKqwI+zNsRoai zV2HABPxmSLJ7cPUB9qNdvxX9amaKW/e7jfwhnokVQ+SvUiZqiOb77JEsdhyHyHm +N3Pq7AsqI1V6/Z2aBv4i9aVXDml1yYtGk0ZfpUPkSOPaTsUoY09MFVFazGfUl+F TQIDAQAB" ; private static readonly string PrivateKey = @"MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDT9WIFJYRlC/o3 fAao2hYPDqHDV76IXKuDZqgvuwVvrsoTHqom5YVATBKO2/5qmsQaZHerflT23Rnd 1DOy1J/Sdn1ergaoOyrhuEGIEOGgpcl/Qbh3hHst4ddv3lncK7Uga2kBOILWe7+T ktu9KSxZqqk09OpbQTqy1SqKNir92WgBcZzJbWPnNaUr3ZFdO0SL9GHflWoqrAj7 M2xGhqLNXYcAE/GZIsntw9QH2o12/Ff1qZopb97uN/CGeiRVD5K9SJmqI5vvskSx 2HIfIeb43c+rsCyojVXr9nZoG/iL1pVcOaXXJi0aTRl+lQ+RI49pOxShjT0wVUVr MZ9SX4VNAgMBAAECggEAfCTf6WXE+q4eOrsw51r8yormYhSVaybj6g2JepNOptA4 WSR/wlJyTmt//x6JEAVf0JmBofdXalOr38p3EUoJ5eoyme7RxV0KS7Rw5XIFxOL1 dsyWb6Ivx3rchRA1j4gmCTv//5AKyfcnCRdeDpf7+vTDMFo2nYZCDBZgWR1K5uyL CZw8d+ha6sVcN5ScusIwD0fu77ReDIaY1X0ekhaqrk7Ddnt16x7rO9C70HWWp2q3 iloeANxtyfvtUQtxzgBkch48/EztJX3rxFtdyYao9DkFeGOMu7gcVzNkFkzXPcBd kt219eJctx56tE6G0uCXxON9XZtdQG/oTJlGtcqsHQKBgQD1Y3IdQCxnFtFqPsDm TbAZ4eBeQtGiPtqFA7jfi0dSMe/qjQvB0k20ELrmW3pDBapYmajAUAEItTzSc85p PZJ4PDFOvgOonaJkyE1bBlJHOaW6yKntZVMOGL0dtPEmM9Ova+Owxckzxc96H3wW tUimBFQTwuKnCm/BX5zn2TJcQwKBgQDdH9qF8cF/uW1oPNZs5NqqZCGC4m4RsNFW 9j7FzIu7oQ3Xh+FxMRMv8t7LXzrgG5WXQh2RBWMicxlOqKTy/Zjl6C/LfS6bRtZR Lmw0MGJI5oVwxfdcSRWV+ToxCi6GsmwvDyVaURX+3MGHvmFAt69UkqN0j54FxeDD KqEUV65HLwKBgQCP1CsVxACCqBg0yvVrx8tZUFCfT1DqZSbV4hmhRVSXc9eoxeVH RMnwqgGydZnS4OY4qlAD8KC6huhQfjpU6xcHzFgmTC9+zG5b3h+hI7JkNwDR2z3m fIZS8+MdH2pdNvFzl6xMd5F3/BChBwVHlhgv3sedEZShzfc1A6LHLkJbWwKBgQDX SLH6gps/fQrV15V0Q4PZLM+rnERJmPrXTbtj3HeW34CYfMSy7XKe1jivjDHIC1Mj Bs2+aZ5Q5fqXqH2fzeNUwy/1UBVWPCtgsm/Kh+jIzRbR6wufn9ASSamsIRuXLJND Zd2aByQBFHCfdm09ExjyoCnfzAuv1y2zFgfpxEv7JQKBgQCw7rPsOlh3EyUpYTeW AOdPedHr8Xi1/ulnVPVVg2zXTSYoeiW+MwyY9B0Y0PvNtHzm3GURPya9IPKg/Wjo 57MbZFtIaOSBXBDCJZeeXVnthOVSYgjkRE6hU91t7sTqrzUrIZ21NTPjp2G1W2X2 QBJoRL5WTt04yIF6Hlkr3L+lww==" ; #endregion } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?