數字簽名(2):DSA
阿新 • • 發佈:2019-01-26
一.DSA :
Digital Signature Algorithm (DSA)是Schnorr和ElGamal簽名演算法的變種,被美國NIST作為DSfS(DigitalSignature Standard)。
二.模型
三.具體的演算法,實現方,祕鑰長度
演算法 | 金鑰長度 | 預設長度 | 簽名長度 | 實現的方 |
SHA1withDSA |
512-65536 (64的整數倍) |
1024 | 同金鑰 | JDK |
SHA224withDSA | 同上 | 1024 | 同金鑰 | BC |
SHA256withDSA | ... | 1024 | 同金鑰 | BC |
SHA384withDSA | ... | 1024 | 同金鑰 | BC |
SHA512withDSA | ... | 1024 | 同金鑰 | BC |
四.具體的程式碼實現(java):
輸出結果:import java.security.InvalidKeyException; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.SignatureException; import java.security.interfaces.DSAPrivateKey; import java.security.interfaces.DSAPublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import org.apache.commons.codec.binary.Base64; public class DSA { static String src = "歐陽草帽"; public static void main(String[] args) throws Exception { // TODO Auto-generated method stub // 獲取公鑰、私鑰 KeyPair keyPair = getKeyPair(); DSAPublicKey dsaPublicKey = getRSPublicKey(keyPair); DSAPrivateKey dsaPrivateKey = getESAPrivateKey(keyPair); byte [] publicKeyEnc = dsaPublicKey.getEncoded(); // 公鑰 byte [] privateKeyEnc = dsaPrivateKey.getEncoded(); //私鑰 //執行簽名 byte[] result = sign(privateKeyEnc); System.out.println("簽名後的資料:"+Base64.encodeBase64String(result)); //驗證簽名 boolean ok = verify(publicKeyEnc, result); System.out.println("簽名驗證的結果:" + ok); } /** * 驗證簽名 * @param publicKeyEnc * @param result * @return * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException * @throws InvalidKeyException * @throws SignatureException */ public static boolean verify(byte[] publicKeyEnc, byte[] result) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, SignatureException { X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicKeyEnc); KeyFactory keyFactory = KeyFactory.getInstance("DSA"); PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec); Signature signature = Signature.getInstance("SHA1withDSA"); signature.initVerify(publicKey); signature.update(src.getBytes()); boolean ok = signature.verify(result); // 驗證結果 return ok; } /** * 執行簽名 * @param privateKeyEnc * @return * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException * @throws InvalidKeyException * @throws SignatureException */ public static byte[] sign(byte[] privateKeyEnc) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, SignatureException { KeyFactory keyFactory = KeyFactory.getInstance("DSA"); PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKeyEnc); PrivateKey priKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec); //構建簽名 Signature signature = Signature.getInstance("SHA1withDSA"); signature.initSign(priKey); signature.update(src.getBytes()); byte [] result = signature.sign(); // 簽名後的資料資訊 return result; } /** * 生成私鑰 * @param keyPair * @return */ public static DSAPrivateKey getESAPrivateKey(KeyPair keyPair) { DSAPrivateKey dsaPrivateKey = (DSAPrivateKey) keyPair.getPrivate(); return dsaPrivateKey; } /** * 生成公鑰 * @param keyPair * @return */ public static DSAPublicKey getRSPublicKey(KeyPair keyPair) { DSAPublicKey dsaPublicKey = (DSAPublicKey) keyPair.getPublic(); return dsaPublicKey; } /** * 生成祕鑰對的材料 * @return * @throws NoSuchAlgorithmException */ private static KeyPair getKeyPair() throws NoSuchAlgorithmException { KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DSA"); keyPairGenerator.initialize(512); KeyPair keyPair = keyPairGenerator.generateKeyPair(); return keyPair; } }
簽名後的資料:MC0CFCNn2mkuMmv61IbezkNhK2DRvPKxAhUAjmh0dBZinEg+kg5e6bMwNqFmx+M=
簽名驗證的結果:true