1.非对称加密加密算法,有两种方式
公钥(Public Key)与私钥(Private Key)是通过一种算法得到的一个密钥对(即一个公钥和一个私钥),公钥是密钥对中公开的部分,私钥则是非公开的部分。公钥通常用于加密会话密钥、验证数字签名,或加密可以用相应的私钥解密的数据。
第一种是签名,使用私钥加密,公钥解密。
用于让所有公钥的所有者验证私钥所有者的身份,并且用来防止私钥所有者发布的信息被篡改。
但不能保证内容不被他人获得。
第二种是加密,用公钥加密,私钥解密。
用于向公钥所有者发布信息,
这个信息可能被篡改,但无法被他人获得
。
要确保安全,那么应该甲乙各自有一个私钥,甲先用乙的公钥加密这段数据,再用自己的私钥加密之后发给乙,这样确保了数据既不被篡改,也不被读取。
2.那么我们采用的做法是
(1)发出去的数据,先用装载私钥,然后私钥签名获得mac,拼在报文后面,发送出去。代码段如下:
String modulus = "8B7D8CAE9C94914FC1AE......";
String exponent = "4782B238DF3372DB602......";
privateKey = RsaUtil.loadPrivateKey(modulus, exponent, 16);
//1.装载私钥
public static RSAPrivateKey loadPrivateKey(String modulus, String exponent, int radix) throws Exception {
BigInteger mod = new BigInteger(modulus, radix);
BigInteger exp = new BigInteger(exponent, radix);
RSAPrivateKeySpec priKeySpec = new RSAPrivateKeySpec(mod, exp);
KeyFactory keyFac = KeyFactory.getInstance(RSA_KEY_TYPE);
return (RSAPrivateKey) keyFac.generatePrivate(priKeySpec);
}
//2.使用私钥签名
byte[] signData = SignatureUtil.signature(sendData.getBytes("utf-8"), privateKey, "");
public static byte[] signature(byte[] plainText, RSAPrivateKey privateKey, String signAlgor) throws Exception {
if(signAlgor == null || signAlgor.equals("")){
signAlgor = SIGNATURE_ALGORITHM;
}
Signature signature=Signature.getInstance(signAlgor);
signature.initSign(privateKey);
signature.update(plainText);
byte[] signData=signature.sign();
return signData;
}
signDataHex = NumberStringUtil.bytesToHexString(signData);
System.out.println("签名数据=["+signDataHex+"]");
} catch (Exception e) {
e.printStackTrace();
}
//3.签名信息加到json中,发送出去
jsonObject.addProperty("mac", signDataHex);
String jsonStr = gson.toJson(jsonObject);
System.out.println("发送的数据"+jsonStr);
遗留的问题:公私钥对是如何生成的?三个参数中的模代表的是什么?对签名算法的深入研究。
(2)我们收到的数据,调加密服务:
-根据接受数据的加密方式,查询数据库,获取解密服务代码。
if (HsmConstant.HSM_METHOD_0003.getpCode().equals(hsm.getHsmMethod())) {
byte[] plainText = NumberStringUtil.hexStringToBytes(hsm.getPlainText());
byte[] signData = NumberStringUtil.hexStringToBytes(hsm.getSignData());
boolean signVerifyResult = encService.signVerified(hsm.getSignAlgor(), plainText, signData,hsm.getModulus(), hsm.getExponent());
hsm.setSignVerifyResult(signVerifyResult);
}
if (result != true) {
//MAC验证失败,抛出异常
throw new BusinessException(BaseErrConstant.RESP_CODE_0020.getpCode());
}
public synchronized boolean signVerified(String signAlgor, byte[] plainText, byte[] signData, String modulus,String exponent) {
RSAPublicKey publicKey;
Boolean signVerify = null;
try {
publicKey = RsaUtil.loadPublicKey(modulus, exponent, 16);
signVerify = SignatureUtil.signVerified(plainText, signData, publicKey, signAlgor);
} catch (Exception e) {
logger.error("Error:", e);
}
return signVerify;
}