DSA签名(非对称加密)

说明:

DSA为非对称加密,非对称加密指加密与解密所使用的密钥不同,分为公钥和私钥,DSA还有数字签名。例如:app发起支付时,使用私钥(私钥一般放服务器用时获取)对订单串生成签名,然后将订单串与签名一起传给服务器,服务器使用公钥和订单串进行签名校验,返回true表示校验通过,否则订单信息就是伪造的。


使用:

public class DSAUtil {
	private static final String algorithm = "DSA";
	private static final String KEY_PUBLIC = "PublicKey";
	private static final String KEY_PRIVATE = "PrivateKey";

	/**
	 * 生成公钥串、私钥串
	 * 
	 * @return Base64编码过的公钥串、Base64编码过的私钥串
	 */
	public static Map<String, String> generatorKey() {
		Map<String, String> map = new HashMap<String, String>();
		try {
			KeyPairGenerator keygen = KeyPairGenerator.getInstance(algorithm);
			// 创建随机产生器
			SecureRandom secureRandom = new SecureRandom();
			secureRandom.setSeed("abcdefg".getBytes());
			keygen.initialize(1024, secureRandom);

			KeyPair keys = keygen.genKeyPair();
			// 生成公钥
			DSAPublicKey publicKey = (DSAPublicKey) keys.getPublic();
			map.put(KEY_PUBLIC, Base64.encode(publicKey.getEncoded()));
			// 生成私钥
			DSAPrivateKey privateKey = (DSAPrivateKey) keys.getPrivate();
			map.put(KEY_PRIVATE, Base64.encode(privateKey.getEncoded()));
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		return map;
	}

	/**
	 * 用私钥对订单串进行签名
	 * 
	 * @param orderInfo 未加密订单串
	 * @param privateKey Base64编码过的私钥串
	 * 
	 * @return Base64编码过的签名串
	 */
	public static String generatorSign(String orderInfo, String privateKey) {
		try {
			// 根据私钥byte[]创建PKCS8EncodedKeySpec对象
			PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(Base64.decode(privateKey));
			// 指定DSA加密算法
			KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
			// 取得私钥对象
			PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
			// 用私钥对订单串进行签名
			Signature signature = Signature.getInstance(keyFactory.getAlgorithm());
			signature.initSign(priKey);
			signature.update(orderInfo.getBytes());
			// 对私钥进行Base64编码
			return Base64.encode(signature.sign());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 校验数字签名
	 * 
	 * @param orderInfo 未加密订单串
	 * @param publicKey Base64编码过的公钥串
	 * @param sign Base64编码过的签名串
	 * 
	 * @return 校验成功返回true, 校验失败返回false
	 */
	public static boolean verifySign(String orderInfo, String publicKey, String sign) {
		try {
			// 根据公钥byte[]创建X509EncodedKeySpec对象
			X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.decode(publicKey));
			// 指定DSA加密算法
			KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
			// 取公钥对象
			PublicKey pubKey = keyFactory.generatePublic(keySpec);
			// 根据公钥和待加密串初始化Signature
			Signature signature = Signature.getInstance(keyFactory.getAlgorithm());
			signature.initVerify(pubKey);
			signature.update(orderInfo.getBytes());
			// 根据公钥和订单串进行签名校验,通过表示正常,否则表示订单串是伪造的。
			return signature.verify(Base64.decode(sign));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	public static void main(String[] args) {
//		// 产生公钥和私钥,保存起来下次使用
//		Map<String, String> keyMap = generatorKey();
//		// 获得公钥
//		String publicKey = keyMap.get(KEY_PUBLIC);
//		// 获得私钥
//		String privateKey = keyMap.get(KEY_PRIVATE);
//		System.err.println("公钥 : " + publicKey);
//		System.err.println("私钥 : " + privateKey);

		String privateKey = "MIIBSwIBADCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoEFgIUFzPw6lbL1g8H4Nj89G55StSxqPQ=";
		String publicKey = "MIIBtzCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYQAAoGAdFQMgDfhSx4MMvmtjRBvEnS+Q6RVLqbi2aweBsQKpsg48FtnJed/MaPhNWonsXltK/9rdeh59rws61FsoLy7A6AA+jYydqIcOG2vK9u94HDg3ueEttZ5of3/KP6bsFLiivfLqMefi9MOGyIafaffpGA+UPI4tPh1E0GH53TnCaI=";
		// 待签名的订单串
		String orderInfo = "orderId=1001&price=10.1&desc=书本&num=1";
		// 产生签名
		String sign = generatorSign(orderInfo, privateKey);
		System.err.println("签名 : " + sign);

		// 验证签名
		boolean result = verifySign(orderInfo, publicKey, sign);
		System.err.println("签名校验结果: " + result);
	}
}

阅读更多

更多精彩内容