
数字签名是一个带有密钥的消息摘要算法,这个密钥包括了公钥和私钥,用于验证数据完整性、认证数据来源和抗否认,遵循OSI参考模型、私钥签名和公钥验证。也是非对称加密算法和消息摘要算法的结合体,常见的数字签名算法主要有RSA、DSA、ECDSA三种。
RSA是目前计算机密码学中最经典算法,也是目前为止使用最广泛的数字签名算法,RSA数字签名算法的密钥实现与RSA的加密算法是一样的,算法的名称都叫RSA。
它的消息传递操作是:
1、由消息发送方构建密匙对,
2、由消息发送的一方公布公钥至消息接收方,
3、消息发送方对消息用私钥做签名处理
4、消息接收方用公钥对消息做验证
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;
}
}以上就是常用数字签名算法是什么的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号