数字签名是一个带有密钥的消息摘要算法,这个密钥包括了公钥和私钥,用于验证数据完整性、认证数据来源和抗否认,遵循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; } }
Atas ialah kandungan terperinci 常用数字签名算法是什么. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!