Java加密技术 之 DSA

DSA
DSA-Digital Signature Algorithm 是Schnorr和ElGamal签名算法的变种,被美国NIST作为DSS(DigitalSignature Standard)。简单的说,这是一种更高级的验证方式,用作数字签名。不单单只有公钥、私钥,还有数字签名。私钥加密生成数字签名,公钥验证数据及签名。如果数据和签名不匹配则认为验证失败!数字签名的作用就是校验数据在传输过程中不被修改。数字签名,是单向加密的升级!
通过java代码实现如下:
Java代码

import java.security.Key; 
import java.security.KeyFactory; 
import java.security.KeyPair; 
import java.security.KeyPairGenerator; 
import java.security.PrivateKey; 
import java.security.PublicKey; 
import java.security.SecureRandom; 
import java.security.Signature; 
import java.security.interfaces.DSAPrivateKey; 
import java.security.interfaces.DSAPublicKey; 
import java.security.spec.PKCS8EncodedKeySpec; 
import java.security.spec.X509EncodedKeySpec; 
import java.util.HashMap; 
import java.util.Map; 
 
/** 
 * DSA安全编码组件 
*/ 
public abstract class DSACoder extends Coder { 
 
 public static final String ALGORITHM = "DSA"; 
 
 /** 
 * 默认密钥字节数 
 * 
 * <pre> 
 * DSA 
 * Default Keysize 1024 
 * Keysize must be a multiple of 64, ranging from 512 to 1024 (inclusive). 
 * </pre> 
 */ 
 private static final int KEY_SIZE = 1024; 
 
 /** 
 * 默认种子 
 */ 
 private static final String DEFAULT_SEED = "0f22507a10bbddd07d8a3082122966e3"; 
 
 private static final String PUBLIC_KEY = "DSAPublicKey"; 
 private static final String PRIVATE_KEY = "DSAPrivateKey"; 
 
 /** 
 * 用私钥对信息生成数字签名 
 * 
 * @param data 
 * 加密数据 
 * @param privateKey 
 * 私钥 
 * 
 * @return 
 * @throws Exception 
 */ 
 public static String sign(byte[] data, String privateKey) throws Exception { 
 // 解密由base64编码的私钥 
 byte[] keyBytes = decryptBASE64(privateKey); 
 
 // 构造PKCS8EncodedKeySpec对象 
 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); 
 
 // KEY_ALGORITHM 指定的加密算法 
 KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM); 
 
 // 取私钥匙对象 
 PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec); 
 
 // 用私钥对信息生成数字签名 
 Signature signature = Signature.getInstance(keyFactory.getAlgorithm()); 
 signature.initSign(priKey); 
 signature.update(data); 
 
 return encryptBASE64(signature.sign()); 
 } 
 
 /** 
 * 校验数字签名 
 * 
 * @param data 
 * 加密数据 
 * @param publicKey 
 * 公钥 
 * @param sign 
 * 数字签名 
 * 
 * @return 校验成功返回true 失败返回false 
 * @throws Exception 
 * 
 */ 
 public static boolean verify(byte[] data, String publicKey, String sign) 
 throws Exception { 
 
 // 解密由base64编码的公钥 
 byte[] keyBytes = decryptBASE64(publicKey); 
 
 // 构造X509EncodedKeySpec对象 
 X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); 
 
 // ALGORITHM 指定的加密算法 
 KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM); 
 
 // 取公钥匙对象 
 PublicKey pubKey = keyFactory.generatePublic(keySpec); 
 
 Signature signature = Signature.getInstance(keyFactory.getAlgorithm()); 
 signature.initVerify(pubKey); 
 signature.update(data); 
 
 // 验证签名是否正常 
 return signature.verify(decryptBASE64(sign)); 
 } 
 
 /** 
 * 生成密钥 
 * 
 * @param seed 
 * 种子 
 * @return 密钥对象 
 * @throws Exception 
 */ 
 public static Map<String, Object> initKey(String seed) throws Exception { 
 KeyPairGenerator keygen = KeyPairGenerator.getInstance(ALGORITHM); 
 // 初始化随机产生器 
 SecureRandom secureRandom = new SecureRandom(); 
 secureRandom.setSeed(seed.getBytes()); 
 keygen.initialize(KEY_SIZE, secureRandom); 
 
 KeyPair keys = keygen.genKeyPair(); 
 
 DSAPublicKey publicKey = (DSAPublicKey) keys.getPublic(); 
 DSAPrivateKey privateKey = (DSAPrivateKey) keys.getPrivate(); 
 
 Map<String, Object> map = new HashMap<String, Object>(2); 
 map.put(PUBLIC_KEY, publicKey); 
 map.put(PRIVATE_KEY, privateKey); 
 
 return map; 
 } 
 
 /** 
 * 默认生成密钥 
 * 
 * @return 密钥对象 
 * @throws Exception 
 */ 
 public static Map<String, Object> initKey() throws Exception { 
 return initKey(DEFAULT_SEED); 
 } 
 
 /** 
 * 取得私钥 
 * 
 * @param keyMap 
 * @return 
 * @throws Exception 
 */ 
 public static String getPrivateKey(Map<String, Object> keyMap) 
 throws Exception { 
 Key key = (Key) keyMap.get(PRIVATE_KEY); 
 
 return encryptBASE64(key.getEncoded()); 
 } 
 
 /** 
 * 取得公钥 
 * 
 * @param keyMap 
 * @return 
 * @throws Exception 
 */ 
 public static String getPublicKey(Map<String, Object> keyMap) 
 throws Exception { 
 Key key = (Key) keyMap.get(PUBLIC_KEY); 
 
 return encryptBASE64(key.getEncoded()); 
 } 
}

再给出一个测试类:
Java代码

import static org.junit.Assert.*; 
 
import java.util.Map; 
 
import org.junit.Test; 

public class DSACoderTest { 
 
 @Test 
 public void test() throws Exception { 
 String inputStr = "abc"; 
 byte[] data = inputStr.getBytes(); 
 
 // 构建密钥 
 Map<String, Object> keyMap = DSACoder.initKey(); 
 
 // 获得密钥 
 String publicKey = DSACoder.getPublicKey(keyMap); 
 String privateKey = DSACoder.getPrivateKey(keyMap); 
 
 System.err.println("公钥:r" + publicKey); 
 System.err.println("私钥:r" + privateKey); 
 
 // 产生签名 
 String sign = DSACoder.sign(data, privateKey); 
 System.err.println("签名:r" + sign); 
 
 // 验证签名 
 boolean status = DSACoder.verify(data, publicKey, sign); 
 System.err.println("状态:r" + status); 
 assertTrue(status); 
 
 } 
 
}

控制台输出:
Console代码
公钥:

MIIBtzCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZp
RV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fn
xqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuE
C/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJ
FnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImo
g9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYQAAoGAIu4RUlcQLp49PI0MrbssOY+3uySVnp0TULSv
5T4VaHoKzsLHgGTrwOvsGA+V3yCNl2WDu3D84bSLF7liTWgOj+SMOEaPk4VyRTlLXZWGPsf1Mfd9
21XAbMeVyKDSHHVGbMjBScajf3bXooYQMlyoHiOt/WrCo+mv7efstMM0PGo=

私钥:

MIIBTAIBADCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2
USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4
O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmC
ouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCB
gLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhR
kImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoEFwIVAIegLUtmm2oQKQJTOiLugHTSjl/q

签名:

MC0CFQCMg0J/uZmF8GuRpr3TNq48w60nDwIUJCyYNah+HtbU6NcQfy8Ac6LeLQs=

状态:
true
注意状态为true,就验证成功!

声明:本文采用 BY-NC-SA 协议进行授权,本文链接:Java加密技术 之 DSA

发表评论