C# Java间进行RSA加密解密交互(二)

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: 原文: C# Java间进行RSA加密解密交互(二) 接着前面一篇文章C# Java间进行RSA加密解密交互,继续探讨这个问题。 在前面,虽然已经实现了C# Java间进行RSA加密解密交互,但是还是与项目中要求的有所出入。
原文: C# Java间进行RSA加密解密交互(二)

接着前面一篇文章C# Java间进行RSA加密解密交互,继续探讨这个问题。

在前面,虽然已经实现了C# Java间进行RSA加密解密交互,但是还是与项目中要求的有所出入。在项目中,客户端(Java)的加密是通过这么一个方法实现的:

/**
 * RSA加密
 * @param text--待加密的明文
 * @param key--公钥,由服务器端提供的经base64编码的字符串
 * @return
 */
public static String RSAEncryptoWithPublicKey(String text, String key) {
	String result = null;
	try {
		byte[] publicKeyByte = base64Decrypto(key);

		X509EncodedKeySpec x509 = new X509EncodedKeySpec(publicKeyByte);
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		PublicKey publicKey = keyFactory.generatePublic(x509);

		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
		cipher.init(Cipher.ENCRYPT_MODE, publicKey);

		result = base64Encrypto(cipher.doFinal(text.getBytes()));
	} catch (Exception e) {
		e.printStackTrace();
		return null;
	}
	return result;
}

在上一篇中的实现,需要客户端先做一次解析工作,而已经开发好的客户端是没有这一层的,所以得想个办法,在服务器端(C#)完成这项工作。但是经过多次尝试,依然未果。于是换一种方式,密钥对不由C#提供,而转而有Java提供,生成客户端需要的公钥形式,并解析公钥私钥,组装C# 的XML格式的密钥对字符串。

下面贴一下RSA密钥对生成代码(参考RSA的密钥把JAVA格式转换成C#的格式

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateCrtKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;

/**
 * @author Administrator
 * 
 */
public class RSAJavaToCSharp {
	public static void main(String[] args) throws Exception {
		HashMap<String, Object> map = getKeys();
		RSAPublicKey publicKey = (RSAPublicKey) map.get("PUBLIC");
		RSAPrivateKey privateKey = (RSAPrivateKey) map.get("PRIVATE");
		
		String publicKeyString = getRSAPublicKeyAsNetFormat(publicKey.getEncoded());
		String privateKeyString = getRSAPrivateKeyAsNetFormat(privateKey.getEncoded());
		
		System.out.println(encodeBase64(publicKey.getEncoded()));//此处为客户端加密时需要的公钥字符串
		System.out.println(encodePublicKeyToXml(publicKey));
		System.out.println(publicKeyString);
		System.out.println(privateKeyString);
	}

	/**获取密钥对
	 * @return
	 * @throws NoSuchAlgorithmException
	 */
	public static HashMap<String, Object> getKeys()
			throws NoSuchAlgorithmException {
		HashMap<String, Object> map = new HashMap<String, Object>();
		KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
		keyPairGen.initialize(1024);
		KeyPair keyPair = keyPairGen.generateKeyPair();
		RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
		RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
		map.put("PUBLIC", publicKey);
		map.put("PRIVATE", privateKey);
		return map;
	}

	/**
	 * 私钥转换成C#格式
	 * @param encodedPrivkey
	 * @return
	 */
	private static String getRSAPrivateKeyAsNetFormat(byte[] encodedPrivateKey) {
		try {
			StringBuffer buff = new StringBuffer(1024);

			PKCS8EncodedKeySpec pvkKeySpec = new PKCS8EncodedKeySpec(
					encodedPrivateKey);
			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
			RSAPrivateCrtKey pvkKey = (RSAPrivateCrtKey) keyFactory
					.generatePrivate(pvkKeySpec);

			buff.append("<RSAKeyValue>");
			buff.append("<Modulus>"
					+ encodeBase64(removeMSZero(pvkKey.getModulus()
							.toByteArray())) + "</Modulus>");

			buff.append("<Exponent>"
					+ encodeBase64(removeMSZero(pvkKey.getPublicExponent()
							.toByteArray())) + "</Exponent>");

			buff.append("<P>"
					+ encodeBase64(removeMSZero(pvkKey.getPrimeP()
							.toByteArray())) + "</P>");

			buff.append("<Q>"
					+ encodeBase64(removeMSZero(pvkKey.getPrimeQ()
							.toByteArray())) + "</Q>");

			buff.append("<DP>"
					+ encodeBase64(removeMSZero(pvkKey.getPrimeExponentP()
							.toByteArray())) + "</DP>");

			buff.append("<DQ>"
					+ encodeBase64(removeMSZero(pvkKey.getPrimeExponentQ()
							.toByteArray())) + "</DQ>");

			buff.append("<InverseQ>"
					+ encodeBase64(removeMSZero(pvkKey.getCrtCoefficient()
							.toByteArray())) + "</InverseQ>");

			buff.append("<D>"
					+ encodeBase64(removeMSZero(pvkKey.getPrivateExponent()
							.toByteArray())) + "</D>");
			buff.append("</RSAKeyValue>");

			return buff.toString();
		} catch (Exception e) {
			System.err.println(e);
			return null;
		}
	}

	/**
	 * 公钥转成C#格式
	 * @param encodedPrivkey
	 * @return
	 */
	private static String getRSAPublicKeyAsNetFormat(byte[] encodedPublicKey) {
		try {
			StringBuffer buff = new StringBuffer(1024);
			
			//Only RSAPublicKeySpec and X509EncodedKeySpec supported for RSA public keys
			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
			RSAPublicKey pukKey = (RSAPublicKey) keyFactory
					.generatePublic(new X509EncodedKeySpec(encodedPublicKey));

			buff.append("<RSAKeyValue>");
			buff.append("<Modulus>"
					+ encodeBase64(removeMSZero(pukKey.getModulus()
							.toByteArray())) + "</Modulus>");
			buff.append("<Exponent>"
					+ encodeBase64(removeMSZero(pukKey.getPublicExponent()
							.toByteArray())) + "</Exponent>");
			buff.append("</RSAKeyValue>");
			return buff.toString();
		} catch (Exception e) {
			System.err.println(e);
			return null;
		}
	}

	/**
	 * 公钥转换成C#格式
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static String encodePublicKeyToXml(PublicKey key) throws Exception {
		if (!RSAPublicKey.class.isInstance(key)) {
			return null;
		}
		RSAPublicKey pubKey = (RSAPublicKey) key;
		StringBuilder sb = new StringBuilder();

		sb.append("<RSAKeyValue>");
		sb.append("<Modulus>")
				.append(encodeBase64(removeMSZero(pubKey.getModulus()
						.toByteArray()))).append("</Modulus>");
		sb.append("<Exponent>")
				.append(encodeBase64(removeMSZero(pubKey.getPublicExponent()
						.toByteArray()))).append("</Exponent>");
		sb.append("</RSAKeyValue>");
		return sb.toString();
	}

	/**
	 * @param data
	 * @return
	 */
	private static byte[] removeMSZero(byte[] data) {
		byte[] data1;
		int len = data.length;
		if (data[0] == 0) {
			data1 = new byte[data.length - 1];
			System.arraycopy(data, 1, data1, 0, len - 1);
		} else
			data1 = data;

		return data1;
	}

	/**
	 * base64编码
	 * @param input
	 * @return
	 * @throws Exception
	 */
	public static String encodeBase64(byte[] input) throws Exception {
		Class clazz = Class
				.forName("com.sun.org.apache.xerces.internal.impl.dv.util.Base64");
		Method mainMethod = clazz.getMethod("encode", byte[].class);
		mainMethod.setAccessible(true);
		Object retObj = mainMethod.invoke(null, new Object[] { input });
		return (String) retObj;
	}

	/**
	 * base64解码 
	 * @param input
	 * @return
	 * @throws Exception
	 */
	public static byte[] decodeBase64(String input) throws Exception {
		Class clazz = Class
				.forName("com.sun.org.apache.xerces.internal.impl.dv.util.Base64");
		Method mainMethod = clazz.getMethod("decode", String.class);
		mainMethod.setAccessible(true);
		Object retObj = mainMethod.invoke(null, input);
		return (byte[]) retObj;
	}

	public static String byteToString(byte[] b)
			throws UnsupportedEncodingException {
		return new String(b, "utf-8");
	}
}

为了方便在服务器端使用,初始想法是想将java文件封装为.dll文件,共C#调用,测试后,发现这样做行不通,bug提示类找不到,这是因为java代码中还导入了其他jar包的缘故。

于是,退而求其次,将上述java文件Export为可执行的jar文件,并将生成的密钥对写入相应文件中。再由C#读取,提供给客户端。

---------------------------------------------------------------------------------------------

C# Java间进行RSA加密解密交互

C# Java间进行RSA加密解密交互(三)

目录
相关文章
|
3月前
|
存储 安全 数据安全/隐私保护
打造安全防线!Python AES&RSA加密工具,黑客绕道走的秘籍
【9月更文挑战第9天】随着数字化时代的到来,信息安全问题日益凸显。本文将介绍如何使用Python结合AES与RSA两种加密算法,构建强大的加密工具。AES以其高效性和强安全性著称,适用于大量数据的快速加密;RSA作为非对称加密算法,在加密小量数据及实现数字签名方面表现卓越。通过整合两者,可以构建既安全又灵活的加密系统。首先,需要安装pycryptodome库。接着,实现AES加密与解密功能,最后利用RSA加密AES密钥,确保其安全传输。这种设计不仅提高了数据传输效率,还增强了密钥交换的安全性,为敏感数据提供坚实保护。
243 43
|
3月前
|
安全 算法 网络安全
浅谈非对称加密(RSA)
浅谈非对称加密(RSA)
170 0
|
2月前
|
Java Maven 数据安全/隐私保护
如何实现Java打包程序的加密代码混淆,避免被反编译?
【10月更文挑战第15天】如何实现Java打包程序的加密代码混淆,避免被反编译?
229 2
|
2月前
|
存储 安全 算法
C#一分钟浅谈:数据加密与解密技术
【10月更文挑战第3天】在数字化时代,信息安全至关重要。数据加密作为保障信息不被未授权访问的有效手段,通过特定算法将明文转换为密文,确保即使数据被截获也难以解读。本文从基础概念入手,介绍C#中实现数据加密的方法,涵盖对称加密(如AES、DES)与非对称加密(如RSA),并通过具体示例代码演示如何使用`System.Security.Cryptography.Aes`类完成AES加密和解密过程。此外,还强调了密钥管理及安全策略的重要性。
87 4
|
2月前
|
算法 安全 Go
RSA加密算法详解与Python和Go实现
RSA加密算法详解与Python和Go实现
176 1
|
2月前
|
算法 安全 网络安全
使用 Python 实现 RSA 加密
使用 Python 实现 RSA 加密
109 2
|
2月前
|
安全 算法 Java
数据库信息/密码加盐加密 —— Java代码手写+集成两种方式,手把手教学!保证能用!
本文提供了在数据库中对密码等敏感信息进行加盐加密的详细教程,包括手写MD5加密算法和使用Spring Security的BCryptPasswordEncoder进行加密,并强调了使用BCryptPasswordEncoder时需要注意的Spring Security配置问题。
210 0
数据库信息/密码加盐加密 —— Java代码手写+集成两种方式,手把手教学!保证能用!
|
3月前
|
存储 安全 算法
RSA在手,安全我有!Python加密解密技术,让你的数据密码坚不可摧
【9月更文挑战第11天】在数字化时代,信息安全至关重要。传统的加密方法已难以应对日益复杂的网络攻击。RSA加密算法凭借其强大的安全性和广泛的应用场景,成为保护敏感数据的首选。本文介绍RSA的基本原理及在Python中的实现方法,并探讨其优势与挑战。通过使用PyCryptodome库,我们展示了RSA加密解密的完整流程,帮助读者理解如何利用RSA为数据提供安全保障。
150 5
|
3月前
|
安全 算法 数据安全/隐私保护
深度揭秘!Python加密技术的背后,AES与RSA如何守护你的数据安全
【9月更文挑战第10天】随着数字化时代的到来,数据安全成为企业和个人面临的重大挑战。Python 作为功能强大的编程语言,在数据加密领域扮演着重要角色。AES 和 RSA 是两种主流加密算法,分别以对称和非对称加密方式保障数据安全。AES(Advanced Encryption Standard)因其高效性和安全性,在数据加密中广泛应用;而 RSA 则利用公钥和私钥机制,在密钥交换和数字签名方面表现卓越。
91 3
|
3月前
|
存储 安全 数据库
双重防护,无懈可击!Python AES+RSA加密方案,构建最强数据安全堡垒
【9月更文挑战第11天】在数字时代,数据安全至关重要。AES与RSA加密技术相结合,构成了一道坚固防线。AES以其高效性保障数据加密,而RSA则确保密钥安全传输,二者相辅相成,提供双重保护。本文通过Python代码示例展示了这一加密方案的魅力,强调了其在实际应用中的重要性和安全性。使用HTTPS等安全协议传输加密密钥和密文,确保数据在数字世界中自由流通而无忧。
83 1