數位簽章是一個帶有金鑰的訊息摘要演算法,這個金鑰包括了公鑰和私鑰,用於驗證資料完整性、認證資料來源和抗否認,遵循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中文網其他相關文章!