Java中使用RSA对请求和接收数据进行签名校验

1、RSA是非对称加密算法,具体原理是什么这里不做解释,给出一篇文章介绍的非常详细。

http://www.ruanyifeng.com/blog/2013/06/rsa_algorithm_part_one.html

2、RSA算法需要 公钥和私钥,具体生成办法有很多种,可以使用工具生成,每种语言也都有相应的API,这里介绍一种通过openssl工具生成的方法。
RSA私钥及公钥生成
Linux用户(以Ubuntu为例) $ openssl 进入OpenSSL程序 OpenSSL> genrsa -out rsa_private_key.pem 1024 生成私钥 OpenSSL> pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt Java开发者需要将私钥转换成PKCS8格式 OpenSSL> rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem 生成公钥 OpenSSL> exit
注意:对于使用Java的开发者,将pkcs8在console中输出的私钥去除头尾、换行和空格,作为开发者私钥,对于.NET和PHP的开发者来说,无需进行pkcs8命令行操作。


私钥:

MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBANjUPqvutSFTALjO
pgjN27bXL8oYY6UKjqNetcaBf1nbnVczPenH2BMehN5iq+ibYf/PgwuMbKIoBGxT
EIvqdm3jAvcaqMYkWQwVW+NQ4AO7bR4IGAcdZXMpnaoS03yeoUC4jm/6nKfv10SL
3bnZpZamznY3eAC5MGsYwzg+D0gzAgMBAAECgYBCS7LV0uiixcQkvVpausaBAw5j
lk1xOucd4GlnxlRv3wwei1ZU0nuobN5nOHgjaM7v7jy9HTRh6CZiEIuwnAGVSx1+
91K042rraLhQ9iomRqxZqymPAF6o+g+QhlPbjC62j1eeJvFivcwzpdH7SPdjdFpm
DX31VYx01HyFYSEqwQJBAP7R7U3S/BduCS6kjEVry2B5u/l597Jr9Eut0M/D7zbJ
gREgCi1OiF1V3c34cnBQhRuhhojD3pm9q/3s9WNn0ZECQQDZ1Ugvsqc/b4lBYFDa
6uaoIjboLB/MGZi3Pr58Q/xMZa1vZQbYeiCAqJQsBvEPnM/HC2HL7zKcHc8C505B
KNuDAkEA3QgdDkd3sZ8ZyeKjZcgl5m5Rtgms6JApnMeNe9qaEezhzof7K+eV81f7
CKF8Kp49h4UpnFJCMRtMJ/s1s18ncQJBAJIMcc2pFoFtorT2gr+EZwmrhuy7SMZr
Ev0pUEW4v1vpgBMDxUc2+rvISzAJp240UQq/Et7MjT4mrjjgJJODdUkCQBeydFAF
Y8LpQkxOStq7+avjgDpZ8wFc6dFEgS/mLbQPERBlYoW/+epGdUdZPYCWv252hf5M
IadwM5a3TQvtDcA=

公钥:

MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDY1D6r7rUhUwC4zqYIzdu21y/K
GGOlCo6jXrXGgX9Z251XMz3px9gTHoTeYqvom2H/z4MLjGyiKARsUxCL6nZt4wL3
GqjGJFkMFVvjUOADu20eCBgHHWVzKZ2qEtN8nqFAuI5v+pyn79dEi9252aWWps52
N3gAuTBrGMM4Pg9IMwIDAQAB


使用私钥对数据签名

	/**
	 * 使用私钥对数据进行加密签名
	 * @param data 数据
	 * @param privateKeyString 私钥
	 * @return 加密后的签名
	 */
	public static String sign(String data, String privateKeyString) throws Exception {
		KeyFactory keyf = KeyFactory.getInstance("RSA");
		PrivateKey privateKey = keyf.generatePrivate(new PKCS8EncodedKeySpec(Base64.decode(privateKeyString)));
		java.security.Signature signet = java.security.Signature.getInstance("MD5withRSA");
		signet.initSign(privateKey);
		signet.update(data.getBytes("utf-8"));
		byte[] signed = signet.sign();
		return Base64.encodeBytes(signed);
	}


使用公钥验证签名正确性

	/**
	 * 使用公钥判断签名是否与数据匹配
	 * @param data 数据
	 * @param sign 签名
	 * @param publicKeyString 公钥
	 * @return 是否篡改了数据
	 */
	public static boolean verify(String data, String sign, String publicKeyString) throws Exception {
		KeyFactory keyf = KeyFactory.getInstance("RSA");
		PublicKey publicKey = keyf.generatePublic(new X509EncodedKeySpec(Base64.decode(publicKeyString)));
		java.security.Signature signet = java.security.Signature.getInstance("MD5withRSA");
		signet.initVerify(publicKey);
		signet.update(data.getBytes("utf-8"));
		return signet.verify(Base64.decode(sign));
	}

测试

		//私钥
		String privateKeyString = FileUtils.readFileToString(new File(
				"E:\\rsa\\rsa_private_key.pem"), "utf-8");

		//公钥
		String publicKeyString = FileUtils.readFileToString(new File(
				"E:\\rsa\\rsa_public_key.pem"), "utf-8");
		
		String data = "testabc";
		String s = sign(data, privateKeyString);
		System.out.println("针对数据["  + data + "]签名: " + s);
		
		data = "testabc";
		
		System.out.println("签名验证结果:" + verify(data, s, publicKeyString));

针对数据[testabc]签名: VERoc+d/3Msd653i5P7r7YRskiMCdxbCi+3PFwGjDKhf1typcUvod32X8gfgWqH5sCWrs0BuRswm
z43As4OK82u47K0zsifYD/AKVqGrp4a6UaCzGJxWjBqlfaqB+n9NbclGAqfpgA0PjuOPLFuXQnBg
EafpudJx3niCQAp1Fiw=
签名验证结果:true


如果data发生变化那么签名检测结果为false,这样就有效的防止了数据被篡改。


  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值