数字签名算法主要包含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;}
}