BlogJava 聯系 聚合 管理  

          Blog Stats

          隨筆檔案


          bitmap

          bitmap

          ECC
          ECC-Elliptic Curves Cryptography,橢圓曲線密碼編碼學,是目前已知的公鑰體制中,對每比特所提供加密強度最高的一種體制。在軟件注冊保護方面起到很大的作用,一般的序列號通常由該算法產生。
              當我開始整理《Java加密技術(二)》的時候,我就已經在開始研究ECC了,但是關于Java實現ECC算法的資料實在是太少了,無論是國內還是國外的資料,無論是官方還是非官方的解釋,最終只有一種答案——ECC算法在jdk1.5后加入支持,目前僅僅只能完成密鑰的生成與解析。
              盡管如此,我照舊提供相應的Java實現代碼,以供大家參考。

          通過java代碼實現如下:Coder類見
          import java.math.BigInteger;   
          import java.security.Key;   
          import java.security.KeyFactory;   
          import java.security.interfaces.ECPrivateKey;   
          import java.security.interfaces.ECPublicKey;   
          import java.security.spec.ECFieldF2m;   
          import java.security.spec.ECParameterSpec;   
          import java.security.spec.ECPoint;   
          import java.security.spec.ECPrivateKeySpec;   
          import java.security.spec.ECPublicKeySpec;   
          import java.security.spec.EllipticCurve;   
          import java.security.spec.PKCS8EncodedKeySpec;   
          import java.security.spec.X509EncodedKeySpec;   
          import java.util.HashMap;   
          import java.util.Map;   
            
          import javax.crypto.Cipher;   
          import javax.crypto.NullCipher;   
            
          import sun.security.ec.ECKeyFactory;   
          import sun.security.ec.ECPrivateKeyImpl;   
          import sun.security.ec.ECPublicKeyImpl;   
            
          /**  
           * ECC安全編碼組件  
           *   
           * 
          @author 梁棟  http://www.bt285.cn http://www.5a520.cn
           * 
          @version 1.0  
           * 
          @since 1.0  
           
          */
            
          public abstract class ECCCoder extends Coder {   
            
              
          public static final String ALGORITHM = "EC";   
              
          private static final String PUBLIC_KEY = "ECCPublicKey";   
              
          private static final String PRIVATE_KEY = "ECCPrivateKey";   
            
              
          /**  
               * 解密<br>  
               * 用私鑰解密  
               *   
               * 
          @param data  
               * 
          @param key  
               * 
          @return  
               * 
          @throws Exception  
               
          */
            
              
          public static byte[] decrypt(byte[] data, String key) throws Exception {   
                  
          // 對密鑰解密   
                  byte[] keyBytes = decryptBASE64(key);   
            
                  
          // 取得私鑰   
                  PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);   
                  KeyFactory keyFactory 
          = ECKeyFactory.INSTANCE;   
            
                  ECPrivateKey priKey 
          = (ECPrivateKey) keyFactory   
                          .generatePrivate(pkcs8KeySpec);   
            
                  ECPrivateKeySpec ecPrivateKeySpec 
          = new ECPrivateKeySpec(priKey.getS(),   
                          priKey.getParams());   
            
                  
          // 對數據解密   
                  
          // TODO Chipher不支持EC算法 未能實現   
                  Cipher cipher = new NullCipher();   
                  
          // Cipher.getInstance(ALGORITHM, keyFactory.getProvider());   
                  cipher.init(Cipher.DECRYPT_MODE, priKey, ecPrivateKeySpec.getParams());   
            
                  
          return cipher.doFinal(data);   
              }
             
            
              
          /**  
               * 加密<br>  
               * 用公鑰加密  
               *   
               * 
          @param data  
               * 
          @param privateKey  
               * 
          @return  
               * 
          @throws Exception  
               
          */
            
              
          public static byte[] encrypt(byte[] data, String privateKey)   
                      
          throws Exception {   
                  
          // 對公鑰解密   
                  byte[] keyBytes = decryptBASE64(privateKey);   
            
                  
          // 取得公鑰   
                  X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);   
                  KeyFactory keyFactory 
          = ECKeyFactory.INSTANCE;   
            
                  ECPublicKey pubKey 
          = (ECPublicKey) keyFactory   
                          .generatePublic(x509KeySpec);   
            
                  ECPublicKeySpec ecPublicKeySpec 
          = new ECPublicKeySpec(pubKey.getW(),   
                          pubKey.getParams());   
            
                  
          // 對數據加密   
                  
          // TODO Chipher不支持EC算法 未能實現   
                  Cipher cipher = new NullCipher();   
                  
          // Cipher.getInstance(ALGORITHM, keyFactory.getProvider());   
                  cipher.init(Cipher.ENCRYPT_MODE, pubKey, ecPublicKeySpec.getParams());   
            
                  
          return cipher.doFinal(data);   
              }
             
            
              
          /**  
               * 取得私鑰  
               *   
               * 
          @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());   
              }
             
            
              
          /**  
               * 初始化密鑰  
               *   
               * 
          @return  
               * 
          @throws Exception  
               
          */
            
              
          public static Map<String, Object> initKey() throws Exception {   
                  BigInteger x1 
          = new BigInteger(   
                          
          "2fe13c0537bbc11acaa07d793de4e6d5e5c94eee8"16);   
                  BigInteger x2 
          = new BigInteger(   
                          
          "289070fb05d38ff58321f2e800536d538ccdaa3d9"16);   
            
                  ECPoint g 
          = new ECPoint(x1, x2);   
            
                  
          // the order of generator   
                  BigInteger n = new BigInteger(   
                          
          "5846006549323611672814741753598448348329118574063"10);   
                  
          // the cofactor   
                  int h = 2;   
                  
          int m = 163;   
                  
          int[] ks = 763 };   
                  ECFieldF2m ecField 
          = new ECFieldF2m(m, ks);   
                  
          // y^2+xy=x^3+x^2+1   
                  BigInteger a = new BigInteger("1"2);   
                  BigInteger b 
          = new BigInteger("1"2);   
            
                  EllipticCurve ellipticCurve 
          = new EllipticCurve(ecField, a, b);   
            
                  ECParameterSpec ecParameterSpec 
          = new ECParameterSpec(ellipticCurve, g,   
                          n, h);   
                  
          // 公鑰   
                  ECPublicKey publicKey = new ECPublicKeyImpl(g, ecParameterSpec);   
            
                  BigInteger s 
          = new BigInteger(   
                          
          "1234006549323611672814741753598448348329118574063"10);   
                  
          // 私鑰  http://www.5a520.cn 
                  ECPrivateKey privateKey = new ECPrivateKeyImpl(s, ecParameterSpec);   
            
                  Map
          <String, Object> keyMap = new HashMap<String, Object>(2);   
            
                  keyMap.put(PUBLIC_KEY, publicKey);   
                  keyMap.put(PRIVATE_KEY, privateKey);   
            
                  
          return keyMap;   
              }
             
            
          }
            
          請注意上述代碼中的TODO內容,再次提醒注意,Chipher不支持EC算法 ,以上代碼僅供參考。Chipher、Signature、KeyPairGenerator、KeyAgreement、SecretKey均不支持EC算法。為了確保程序能夠正常執行,我們使用了NullCipher類,驗證程序。

          照舊提供一個測試類:
          import static org.junit.Assert.*;   
            
          import java.math.BigInteger;   
          import java.security.spec.ECFieldF2m;   
          import java.security.spec.ECParameterSpec;   
          import java.security.spec.ECPoint;   
          import java.security.spec.ECPrivateKeySpec;   
          import java.security.spec.ECPublicKeySpec;   
          import java.security.spec.EllipticCurve;   
          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 ECCCoderTest {   
            
              @Test  
              
          public void test() throws Exception {   
                  String inputStr 
          = "abc";   
                  
          byte[] data = inputStr.getBytes();   
            
                  Map
          <String, Object> keyMap = ECCCoder.initKey();   
            
                  String publicKey 
          = ECCCoder.getPublicKey(keyMap);   
                  String privateKey 
          = ECCCoder.getPrivateKey(keyMap);   
                  System.err.println(
          "公鑰: \n" + publicKey);   
                  System.err.println(
          "私鑰: \n" + privateKey);   
            
                  
          byte[] encodedData = ECCCoder.encrypt(data, publicKey);   
            
                  
          byte[] decodedData = ECCCoder.decrypt(encodedData, privateKey);   
            
                  String outputStr 
          = new String(decodedData);   
                  System.err.println(
          "加密前: " + inputStr + "\n\r" + "解密后: " + outputStr);   
                  assertEquals(inputStr, outputStr);   
              }
             
          }
            
          公鑰:    
          MEAwEAYHKoZIzj0CAQYFK4EEAAEDLAAEAv4TwFN7vBGsqgfXk95ObV5clO7oAokHD7BdOP9YMh8u   
          gAU21TjM2qPZ   
            
          私鑰:    
          MDICAQAwEAYHKoZIzj0CAQYFK4EEAAEEGzAZAgEBBBTYJsR3BN7TFw7JHcAHFkwNmfil7w==   
            
          加密前: abc   
            
          解密后: abc  
          posted on 2009-07-19 09:08 bitmap 閱讀(1559) 評論(0)  編輯  收藏
          主站蜘蛛池模板: 崇礼县| 石城县| 龙南县| 苗栗县| 鄱阳县| 临潭县| 大关县| 通州区| 大厂| 无为县| 宁陕县| 正定县| 蚌埠市| 确山县| 苍溪县| 晋中市| 浙江省| 武隆县| 广河县| 郁南县| 犍为县| 宜州市| 马鞍山市| 甘肃省| 汝州市| 东山县| 额尔古纳市| 仁化县| 临沭县| 梨树县| 黄大仙区| 波密县| 泰和县| 建水县| 建昌县| 吉安市| 得荣县| 渭源县| 阿荣旗| 漳浦县| 招远市|