数字签名之RSASignature

1、RSA 签名算法概念

     将 RSA 公钥密码算法按照数字签名的方式运用

2、RSA 签名算法分类(JDK实现)

     (1)MD (MD2withRSA、MD5withRSA)
     (2)SHA (SHA1withRSA、SHA256withRSA、SHA384withRSA、SHA512withRSA)

3、RSASignature 算法的编

     3.1 签名

       

     3.2 验证

            

4、RSASignature算法的实现

import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

public class RSASignatureUtil {

	public static final String KEY_ALGORITHM = "RSA";
	public static final String RSA_PUBLIC_KEY = "RSA_PUBLIC_KEY";
	public static final String RSA_PRIVATE_KEY = "RSA_PRIVATE_KEY";
	public static final String SIGNATURE_ALGORITHM = "MD5withRSA";

	/**
	 * 生成 公私钥 密钥对
	 * 
	 * @return
	 */
	public static Map<String, Object> initKey() {
		try {
			KeyPairGenerator keyPairGenerator = KeyPairGenerator
					.getInstance(KEY_ALGORITHM);
			KeyPair keyPair = keyPairGenerator.generateKeyPair();
			RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
			RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
			Map<String, Object> keyMap = new HashMap<String, Object>();
			keyMap.put(RSA_PUBLIC_KEY, publicKey);
			keyMap.put(RSA_PRIVATE_KEY, privateKey);
			return keyMap;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}

	}

	/**
	 * 获取公钥
	 * 
	 * @param keyMap
	 * @return
	 */
	public static byte[] getPublicKey(Map<String, Object> keyMap) {
		RSAPublicKey key = (RSAPublicKey) keyMap.get(RSA_PUBLIC_KEY);
		return key.getEncoded();
	}

	/**
	 * 获取密钥
	 * 
	 * @param keyMap
	 * @return
	 */
	public static byte[] getPrivateKey(Map<String, Object> keyMap) {
		RSAPrivateKey key = (RSAPrivateKey) keyMap.get(RSA_PRIVATE_KEY);
		return key.getEncoded();
	}

	/**
	 * 对 原始数据 用 私钥 进行签名
	 * 
	 * @param data
	 *            要签名的数据
	 * @param privateKey
	 *            私钥
	 * @return
	 */
	public static byte[] sign(byte[] data, byte[] privateKey) {
		try {
			PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKey);
			KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
			PrivateKey priKey = keyFactory.generatePrivate(keySpec);

			Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
			signature.initSign(priKey);
			signature.update(data);
			return signature.sign();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}

	}

	/**
	 * 根据 原始数据、公钥、签名值 进行验证
	 * 
	 * @param data
	 *            原始数据
	 * @param publicKey
	 *            公钥
	 * @param sign
	 *            签名
	 * @return
	 */
	public static boolean verify(byte[] data, byte[] publicKey, byte[] sign) {
		try {
			X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKey);
			KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
			PublicKey pubKey = keyFactory.generatePublic(keySpec);

			Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
			signature.initVerify(pubKey);
			signature.update(data);
			boolean isValid = signature.verify(sign);
			return isValid;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}

	}

}
字节数组转16进制

public class BytesToHex {

	public static String fromBytesToHex(byte[] resultBytes) {
		StringBuilder builder = new StringBuilder();
		for (int i = 0; i < resultBytes.length; i++) {
			if (Integer.toHexString(0xFF & resultBytes[i]).length() == 1) {
				builder.append("0").append(
						Integer.toHexString(0xFF & resultBytes[i]));
			} else {
				builder.append(Integer.toHexString(0xFF & resultBytes[i]));
			}
		}
		return builder.toString();
	}

}
测试代码

import java.util.Map;

public class Test {
	// 待加密的明文
	public static final String DATA = "test";

	public static void main(String[] args) throws Exception {
		// Test RSASignature
		// 初始化密钥对
		Map<String, Object> keyMap = RSASignatureUtil.initKey();
		byte[] rsaPublicKey = RSASignatureUtil.getPublicKey(keyMap);
		byte[] rsaPrivateKey = RSASignatureUtil.getPrivateKey(keyMap);
		System.out.println("RSASignature PublicKey : "
				+ BytesToHex.fromBytesToHex(rsaPublicKey));
		System.out.println("RSASignature PrivateKey : "
				+ BytesToHex.fromBytesToHex(rsaPrivateKey));

		// Sign
		byte[] sign = RSASignatureUtil.sign(DATA.getBytes(), rsaPrivateKey);
		System.out.println("RSA Sign : " + BytesToHex.fromBytesToHex(sign));

		// Verify
		boolean isValid = RSASignatureUtil.verify((DATA).getBytes(),
				rsaPublicKey, sign);
		System.out.println("RSA Verify : " + isValid);
	}
}

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值