1. 程式人生 > >java加密簽名程式碼備忘

java加密簽名程式碼備忘

這類程式碼很容易忘記,所以記到這裡,以後方便翻閱:

package com.olivephone.olivestat.task;

import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.Cipher;

import org.junit.Test;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class ChiperTest {
	public static final String ALGORITHM = "RSA";
	public static final String SIGNATURE_ALGORITHM = "MD5withRSA";

	@Test
	public void test() throws Exception {

		// 先在服務端先成一個金鑰對,將PrivateKey發給客戶端
		String[] keyPair = createKeyPair();
		String data = "helloworld";

		// Client:1.客戶端將要傳送的資料data,用PrivateKey加密後,生成加密資料data1
		byte[] data1 = encryptByPrivateKey(data.getBytes(), keyPair[0]);
		System.out.println("加密後>>" + encryptBASE64(data1));

		// Client:2.客戶端將加密資料data1用PrivateKey生成簽名sign,
		// Client:3.客戶端要傳送的資料包括:data1,sign
		String sign = sign(keyPair[0], new String(data1));

		// Server:1.服務端接收到客戶端傳送過來的:data1,sign;
		// Server:2.服務端用PublicKey和sign,來驗證data1的簽名是否正確
		boolean success = verify(sign, keyPair[1], new String(data1));

		// Server:3.服務端如果簽名正確,則用PublicKey將data1解密=>data2,即為客戶端傳送過來的明文資料
		byte[] data2 = decryptByPublicKey(data1, keyPair[1]);
		System.out.println("解密後>>" + new String(data2));
		System.out.println(success);
	}

	public String[] createKeyPair() {
		KeyPairGenerator keyGen;
		try {
			keyGen = KeyPairGenerator.getInstance(ALGORITHM);
			keyGen.initialize(1024, new SecureRandom());
			KeyPair keypair = keyGen.generateKeyPair();
			return new String[] { encryptBASE64(keypair.getPrivate().getEncoded()), encryptBASE64(keypair.getPublic().getEncoded()) };
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/* 簽名相關 */
	public String sign(String key, String data) throws Exception {
		byte[] keyBytes = decryptBASE64(key);

		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
		PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);

		Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
		signature.initSign(priKey);
		signature.update(data.getBytes());

		String sign = encryptBASE64(signature.sign());
		return sign;
	}

	public boolean verify(String sign, String key, String data) throws Exception {
		byte[] keyBytes = decryptBASE64(key);

		X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
		PublicKey pubKey = keyFactory.generatePublic(keySpec);

		Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
		signature.initVerify(pubKey);
		signature.update(data.getBytes());

		return signature.verify(decryptBASE64(sign));
	}

	/* 加密相關 */
	public static byte[] encryptByPublicKey(byte[] data, String key) throws Exception {
		byte[] keyBytes = decryptBASE64(key);

		X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
		Key publicKey = keyFactory.generatePublic(x509KeySpec);

		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
		cipher.init(Cipher.ENCRYPT_MODE, publicKey);

		return cipher.doFinal(data);
	}

	public static byte[] decryptByPrivateKey(byte[] data, String key) throws Exception {
		byte[] keyBytes = decryptBASE64(key);

		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
		Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);

		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
		cipher.init(Cipher.DECRYPT_MODE, privateKey);

		return cipher.doFinal(data);
	}

	public static byte[] encryptByPrivateKey(byte[] data, String key) throws Exception {
		byte[] keyBytes = decryptBASE64(key);

		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
		Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);

		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
		cipher.init(Cipher.ENCRYPT_MODE, privateKey);

		return cipher.doFinal(data);
	}

	public static byte[] decryptByPublicKey(byte[] data, String key) throws Exception {
		byte[] keyBytes = decryptBASE64(key);

		X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
		Key publicKey = keyFactory.generatePublic(x509KeySpec);

		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
		cipher.init(Cipher.DECRYPT_MODE, publicKey);

		return cipher.doFinal(data);
	}

	public static byte[] decryptBASE64(String key) throws Exception {
		return (new BASE64Decoder()).decodeBuffer(key);
	}

	public static String encryptBASE64(byte[] key) throws Exception {
		return (new BASE64Encoder()).encodeBuffer(key);
	}
}