月度存档: 四月 2015 - 第2页

数据流加密

最近看了下数据流加密。

最初项目组采用了rc4加密,但双方密钥直接明文存储。被确解的可能性很大。

看了云风介绍了,使用dh进行rc4密钥交换,遂动手进行处理。

dh是非对称加密算法,用于交换密钥。

服务器使用java

客户端使用c#

采了几个坑:

1、java中pubkey使用X509格式存储,prikey使用PKCS8格式存储,如果要取到原始明文,需要使用:

public static Map<String, BigInteger> initKeyRaw() {
		try {
			KeyPairGenerator gen = KeyPairGenerator.getInstance("DH");
			gen.initialize(KEY_SIZE);

			KeyPair keyPair = gen.generateKeyPair();

			DHPublicKey dhPublicKey = (DHPublicKey) keyPair.getPublic();
			DHPrivateKey dhPrivateKey = (DHPrivateKey) keyPair.getPrivate();

			Map<String, BigInteger> ret = Maps.newHashMap();
			ret.put("x", dhPrivateKey.getX());
			ret.put("y", dhPublicKey.getY());
			ret.put("p", dhPublicKey.getParams().getP());
			ret.put("g", dhPublicKey.getParams().getG());
			return ret;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public static Map<String, BigInteger> initKeyRaw(BigInteger y, BigInteger p, BigInteger g) {
		try {
			KeySpec keySpec = new DHPublicKeySpec(y, p, g);
			KeyFactory keyFactory = KeyFactory.getInstance("DH");
			PublicKey pubKey = keyFactory.generatePublic(keySpec);
			DHParameterSpec dhParamSpec = ((DHPublicKey) pubKey).getParams();

			KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(keyFactory.getAlgorithm());
			keyPairGenerator.initialize(dhParamSpec);

			KeyPair keyPair = keyPairGenerator.generateKeyPair();

			DHPublicKey dhPublicKey = (DHPublicKey) keyPair.getPublic();
			DHPrivateKey dhPrivateKey = (DHPrivateKey) keyPair.getPrivate();
			Map<String, BigInteger> ret = Maps.newHashMap();
			ret.put("x", dhPrivateKey.getX());
			ret.put("y", dhPublicKey.getY());
			ret.put("p", dhPublicKey.getParams().getP());
			ret.put("g", dhPublicKey.getParams().getG());
			return ret;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

2、第二个坑

在网上找了一个c#版的dh源码,如果发现两边生成的key怎么都不对,最后定位到,java 中的biginteger是带符号位的。c#版中的biginteger是无符号位的,计算结果当然就不正确了。

我的解决方式是在java中转为biginterger前,添加“00”,这样避免了biginteger变为负数。