BlogJava 联系 聚合 管理  

Blog Stats

随笔档案


bitmap

bitmap

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


通过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安全编码组件  
http://www.bt285.cn http://www.5a520.cn 
 *   
 * 
@author 梁栋  
 * 
@version 1.0  
 * 
@since 1.0  
 
*/
  
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());   
    }
   
}
  

 

再给出一个测试类:

import static org.junit.Assert.*;   
  
import java.util.Map;   
  
import org.junit.Test;   
  
/**  
 *   
 * 
@author 梁栋  http://www.5a520.cn  http://www.feng123.com
 * 
@version 1.0  
 * 
@since 1.0  
 
*/
  
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);   
  
    }
   
  
}
  

 

控制台输出:

公钥:   
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  
posted on 2009-07-17 21:27 bitmap 阅读(1084) 评论(0)  编辑  收藏