1. 程式人生 > >數字簽名演算法

數字簽名演算法

數字簽名演算法主要包含RSA、DSA、ECDSA三種演算法

1. 它的訊息傳遞操作是:

  • 由訊息傳送方構建密匙對,
  • 由訊息傳送的一方公佈公鑰至訊息接收方,
  • 訊息傳送方對訊息用私鑰做簽名處理
  • 訊息接收方用公鑰對訊息做驗證

2. RSA簽名演算法主要分為MD系列和SHA系列。具體實現如下:
在這裡插入圖片描述

3. RSA的數字簽名程式碼實現:
DSA簽名實現類似,ECDSA實現相比前兩者在密匙對成功的方式上存在差別。

import org.apache.commons.codec.binary.Base64;

import java.security.
*; 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 RSASignature { private static final String KEY_ALGORITHM=
"RSA"; private static final String SIGNATURE_ALGORITHM="MD5withRSA"; private static final String PUBLIC_KEY="RSAPublicKey"; private static final String PRIVATE_KEY="RSAPrivateKey"; /** * RSA密匙長度,預設是1024位,密匙長度必須是在64的倍數 * 範圍是512--65536之間 * */ private static final int
KEY_SIZE = 512; public static void main(String[] args) throws Exception { String str = "hello vison"; Map<String, Object> map = initKey(); byte[] privateKey = getPrivateKey(map); //簽名 byte[] signData = sign(str.getBytes(), privateKey); System.out.println("signData: " + Base64.encodeBase64(signData)); //校驗 byte[] pulicKey = getPulicKey(map); boolean status = verify(str.getBytes(), pulicKey, signData); System.out.println("verify result: " + status); } /** * * @param data 待校驗的資料 * @param key 公鑰 * @param sign 資料簽名 * @return boolean 校驗成功返回true,否則返回false * @throws Exception */ public static boolean verify(byte[] data,byte[] key,byte[] sign)throws Exception{ //獲取公鑰 X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(key); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec); //校驗資料 Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initVerify(publicKey); signature.update(data); return signature.verify(sign); } /** * 私鑰簽名 * @param data 待簽名資料 * @param key 私鑰 * @return byte[] 加密資料 * @throws Exception */ public static byte[] sign(byte[] data,byte[] key) throws Exception { //獲取私鑰 PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(key); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec); //簽名 Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initSign(privateKey); signature.update(data); return signature.sign(); } /** * 獲取私鑰 * @param keyMap * @return */ public static byte[] getPrivateKey(Map<String,Object> keyMap){ Key key = (Key) keyMap.get(PRIVATE_KEY); return key.getEncoded(); } /** * 獲取公鑰 * @param keyMap * @return */ public static byte[] getPulicKey(Map<String,Object> keyMap){ Key key = (Key) keyMap.get(PUBLIC_KEY); return key.getEncoded(); } /** * 初始化密匙對 * @return Map 金鑰map * @throws Exception */ public static Map<String,Object> initKey() throws Exception { //例項化金鑰對生成器 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM); //初始化 keyPairGenerator.initialize(KEY_SIZE); //生成密匙對 KeyPair keyPair = keyPairGenerator.genKeyPair(); //私鑰 RSAPrivateKey privateKey = (RSAPrivateKey)keyPair.getPrivate(); //公鑰 RSAPublicKey publicKey = (RSAPublicKey)keyPair.getPublic(); //封裝金鑰 HashMap<String, Object> map = new HashMap<>(2); map.put(PUBLIC_KEY,publicKey); map.put(PRIVATE_KEY,privateKey); return map; } }