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 閱讀(1098) 評論(0)  編輯  收藏
          主站蜘蛛池模板: 项城市| 温宿县| 化德县| 岳阳市| 鹤山市| 辰溪县| 兴安盟| 焦作市| 孟连| 文登市| 万山特区| 崇仁县| 大新县| 无极县| 临汾市| 临邑县| 邵阳县| 来宾市| 永春县| 临武县| 雷州市| 大冶市| 容城县| 沙河市| 凤翔县| 韶山市| 双峰县| 翁牛特旗| 博兴县| 尖扎县| 光山县| 察雅县| 靖江市| 岢岚县| 巩义市| 博爱县| 宜宾市| 达日县| 黄骅市| 农安县| 吉安县|