C# Java RSA互通

 Java代码

 
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# 代码

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


    }

  

posted @ 2023-02-16 15:38  兴趣就是天赋  阅读(21)  评论(0编辑  收藏  举报