RSA是目前计算机密码学中最经典算法,也是目前为止使用最广泛的数字签名算法,RSA数字签名算法的密钥实现与RSA的加密算法是一样的,算法的名称都叫RSA。密钥的产生和转换都是一样的,包括在售的所有SSL数字证书、代码签名证书、文档签名以及邮件签名大多都采用RSA算法进行加密。
RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的绝大多数密码攻击,已被ISO推荐为公钥数据加密标准。
RSA数字签名算法主要包括MD和SHA两种算法,例如我们熟知的MD5和SHA-256即是这两种算法中的一类,具体如下表格分布:
示例代码:
import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; public class HelloRSA { private final static String SIGNATURE_ALGORITHM = "RSA"; private final static String KEY_ALGORITHM = "SHA256withRSA"; // MD5withRSA private final static String src = "Hello World"; public static void main(String[] args) { jdkRSA(); } public static void jdkRSA() { try { //1.初始化密钥 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(SIGNATURE_ALGORITHM); keyPairGenerator.initialize(512); // 位(64的整数倍) KeyPair keyPair = keyPairGenerator.generateKeyPair(); RSAPublicKey rsaPublicKey = (RSAPublicKey)keyPair.getPublic(); //公钥 RSAPrivateKey rsaPrivateKey = (RSAPrivateKey)keyPair.getPrivate(); //私钥 //2.执行签名 //PKCS8EncodedKeySpec类表示私钥的ASN.1编码。 PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded()); KeyFactory keyFactory = KeyFactory.getInstance(SIGNATURE_ALGORITHM); PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec); //签名 Signature signature = Signature.getInstance(KEY_ALGORITHM); signature.initSign(privateKey); signature.update(src.getBytes()); byte[] result = signature.sign(); System.out.println("jdk "+SIGNATURE_ALGORITHM+" sign : " + bytesToHexString(result)); //3.验证签名 //X509EncodedKeySpec类表示根据ASN.1类型SubjectPublicKeyInfo编码的公钥的ASN.1编码。 X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded()); keyFactory = KeyFactory.getInstance(SIGNATURE_ALGORITHM); PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec); //验签 signature = Signature.getInstance(KEY_ALGORITHM); signature.initVerify(publicKey); signature.update(src.getBytes()); boolean bool = signature.verify(result); System.out.println("jdk "+SIGNATURE_ALGORITHM+" verify : " + bool); } catch (Exception e) { e.printStackTrace(); } } /** * byte[] 转 16进制 */ private static String bytesToHexString(byte[] src) { StringBuilder stringBuilder = new StringBuilder(); if (src == null || src.length <= 0) { return null; } for (int i = 0; i < src.length; i++) { int v = src[i] & 0xFF; String hv = Integer.toHexString(v); if (hv.length() < 2) { stringBuilder.append(0); } stringBuilder.append(hv); } return stringBuilder.toString(); } } 6.数字签名算法—DSADSA全称Digital Signature Algorithm,DSA只是一种算法,和RSA不同之处在于它不能用作加密和解密,也不能进行密钥交换,只用于签名,所以它比RSA要快很多,其安全性与RSA相比差不多。DSA的一个重要特点是两个素数公开,这样,当使用别人的p和q时,即使不知道私钥,你也能确认它们是否是随机产生的,还是作了手脚。RSA算法却做不到。
具体算法种类如下图:
示例代码:
import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.interfaces.DSAPrivateKey; import java.security.interfaces.DSAPublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; public class HelloDSA { private final static String SIGNATURE_ALGORITHM = "DSA"; private final static String KEY_ALGORITHM = "SHA1withDSA"; private final static String src = "Hello World"; public static void main(String[] args) { jdkDSA(); } public static void jdkDSA() { try { //1.初始化密钥 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(SIGNATURE_ALGORITHM); keyPairGenerator.initialize(512); // 位(64的整数倍) KeyPair keyPair = keyPairGenerator.generateKeyPair(); DSAPublicKey dsaPublicKey = (DSAPublicKey)keyPair.getPublic(); //公钥 DSAPrivateKey dsaPrivateKey = (DSAPrivateKey)keyPair.getPrivate(); //私钥 //2.执行签名 //PKCS8EncodedKeySpec类表示私钥的ASN.1编码。 PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(dsaPrivateKey.getEncoded()); KeyFactory keyFactory = KeyFactory.getInstance(SIGNATURE_ALGORITHM); PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec); //签名 Signature signature = Signature.getInstance(KEY_ALGORITHM); signature.initSign(privateKey); signature.update(src.getBytes()); byte[] result = signature.sign(); System.out.println("jdk "+SIGNATURE_ALGORITHM+" sign : " + bytesToHexString(result)); //3.验证签名 //X509EncodedKeySpec类表示根据ASN.1类型SubjectPublicKeyInfo编码的公钥的ASN.1编码。 X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(dsaPublicKey.getEncoded()); keyFactory = KeyFactory.getInstance(SIGNATURE_ALGORITHM); PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec); //验签 signature = Signature.getInstance(KEY_ALGORITHM); signature.initVerify(publicKey); signature.update(src.getBytes()); boolean bool = signature.verify(result); System.out.println("jdk "+SIGNATURE_ALGORITHM+" verify : " + bool); } catch (Exception e) { e.printStackTrace(); } } /** * byte[] 转 16进制 */ private static String bytesToHexString(byte[] src) { StringBuilder stringBuilder = new StringBuilder(); if (src == null || src.length <= 0) { return null; } for (int i = 0; i < src.length; i++) { int v = src[i] & 0xFF; String hv = Integer.toHexString(v); if (hv.length() < 2) { stringBuilder.append(0); } stringBuilder.append(hv); } return stringBuilder.toString(); } } 7.数字签名算法—ECDSA