zoukankan      html  css  js  c++  java
  • ECC-Elliptic Curves Cryptography,椭圆曲线密码编码学

    ECC
    ECC-Elliptic Curves Cryptography,椭圆曲线密码编码学,是目前已知的公钥体制中,对每比特所提供加密强度最高的一种体制。在软件注册保护方面起到很大的作用,一般的序列号通常由该算法产生。
        当我开始整理《Java加密技术(二)》的时候,我就已经在开始研究ECC了,但是关于Java实现ECC算法的资料实在是太少了,无论是国内还是国外的资料,无论是官方还是非官方的解释,最终只有一种答案——ECC算法在jdk1.5后加入支持,目前仅仅只能完成密钥的生成与解析。 如果想要获得ECC算法实现,需要调用硬件完成加密/解密(ECC算法相当耗费资源,如果单纯使用CPU进行加密/解密,效率低下),涉及到Java Card领域,PKCS#11。 其实,PKCS#11配置很简单,但缺乏硬件设备,无法尝试!

        尽管如此,我照旧提供相应的Java实现代码,以供大家参考。

    通过java代码实现如下:Coder类见 Java加密技术(一)

    Java代码  收藏代码
    1. import java.math.BigInteger;  
    2. import java.security.Key;  
    3. import java.security.KeyFactory;  
    4. import java.security.interfaces.ECPrivateKey;  
    5. import java.security.interfaces.ECPublicKey;  
    6. import java.security.spec.ECFieldF2m;  
    7. import java.security.spec.ECParameterSpec;  
    8. import java.security.spec.ECPoint;  
    9. import java.security.spec.ECPrivateKeySpec;  
    10. import java.security.spec.ECPublicKeySpec;  
    11. import java.security.spec.EllipticCurve;  
    12. import java.security.spec.PKCS8EncodedKeySpec;  
    13. import java.security.spec.X509EncodedKeySpec;  
    14. import java.util.HashMap;  
    15. import java.util.Map;  
    16.   
    17. import javax.crypto.Cipher;  
    18. import javax.crypto.NullCipher;  
    19.   
    20. import sun.security.ec.ECKeyFactory;  
    21. import sun.security.ec.ECPrivateKeyImpl;  
    22. import sun.security.ec.ECPublicKeyImpl;  
    23.   
    24. /** 
    25.  * ECC安全编码组件 
    26.  *  
    27.  * @author 梁栋 
    28.  * @version 1.0 
    29.  * @since 1.0 
    30.  */  
    31. public abstract class ECCCoder extends Coder {  
    32.   
    33.     public static final String ALGORITHM = "EC";  
    34.     private static final String PUBLIC_KEY = "ECCPublicKey";  
    35.     private static final String PRIVATE_KEY = "ECCPrivateKey";  
    36.   
    37.     /** 
    38.      * 解密<br> 
    39.      * 用私钥解密 
    40.      *  
    41.      * @param data 
    42.      * @param key 
    43.      * @return 
    44.      * @throws Exception 
    45.      */  
    46.     public static byte[] decrypt(byte[] data, String key) throws Exception {  
    47.         // 对密钥解密  
    48.         byte[] keyBytes = decryptBASE64(key);  
    49.   
    50.         // 取得私钥  
    51.         PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);  
    52.         KeyFactory keyFactory = ECKeyFactory.INSTANCE;  
    53.   
    54.         ECPrivateKey priKey = (ECPrivateKey) keyFactory  
    55.                 .generatePrivate(pkcs8KeySpec);  
    56.   
    57.         ECPrivateKeySpec ecPrivateKeySpec = new ECPrivateKeySpec(priKey.getS(),  
    58.                 priKey.getParams());  
    59.   
    60.         // 对数据解密  
    61.         // TODO Chipher不支持EC算法 未能实现  
    62.         Cipher cipher = new NullCipher();  
    63.         // Cipher.getInstance(ALGORITHM, keyFactory.getProvider());  
    64.         cipher.init(Cipher.DECRYPT_MODE, priKey, ecPrivateKeySpec.getParams());  
    65.   
    66.         return cipher.doFinal(data);  
    67.     }  
    68.   
    69.     /** 
    70.      * 加密<br> 
    71.      * 用公钥加密 
    72.      *  
    73.      * @param data 
    74.      * @param privateKey 
    75.      * @return 
    76.      * @throws Exception 
    77.      */  
    78.     public static byte[] encrypt(byte[] data, String privateKey)  
    79.             throws Exception {  
    80.         // 对公钥解密  
    81.         byte[] keyBytes = decryptBASE64(privateKey);  
    82.   
    83.         // 取得公钥  
    84.         X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);  
    85.         KeyFactory keyFactory = ECKeyFactory.INSTANCE;  
    86.   
    87.         ECPublicKey pubKey = (ECPublicKey) keyFactory  
    88.                 .generatePublic(x509KeySpec);  
    89.   
    90.         ECPublicKeySpec ecPublicKeySpec = new ECPublicKeySpec(pubKey.getW(),  
    91.                 pubKey.getParams());  
    92.   
    93.         // 对数据加密  
    94.         // TODO Chipher不支持EC算法 未能实现  
    95.         Cipher cipher = new NullCipher();  
    96.         // Cipher.getInstance(ALGORITHM, keyFactory.getProvider());  
    97.         cipher.init(Cipher.ENCRYPT_MODE, pubKey, ecPublicKeySpec.getParams());  
    98.   
    99.         return cipher.doFinal(data);  
    100.     }  
    101.   
    102.     /** 
    103.      * 取得私钥 
    104.      *  
    105.      * @param keyMap 
    106.      * @return 
    107.      * @throws Exception 
    108.      */  
    109.     public static String getPrivateKey(Map<String, Object> keyMap)  
    110.             throws Exception {  
    111.         Key key = (Key) keyMap.get(PRIVATE_KEY);  
    112.   
    113.         return encryptBASE64(key.getEncoded());  
    114.     }  
    115.   
    116.     /** 
    117.      * 取得公钥 
    118.      *  
    119.      * @param keyMap 
    120.      * @return 
    121.      * @throws Exception 
    122.      */  
    123.     public static String getPublicKey(Map<String, Object> keyMap)  
    124.             throws Exception {  
    125.         Key key = (Key) keyMap.get(PUBLIC_KEY);  
    126.   
    127.         return encryptBASE64(key.getEncoded());  
    128.     }  
    129.   
    130.     /** 
    131.      * 初始化密钥 
    132.      *  
    133.      * @return 
    134.      * @throws Exception 
    135.      */  
    136.     public static Map<String, Object> initKey() throws Exception {  
    137.         BigInteger x1 = new BigInteger(  
    138.                 "2fe13c0537bbc11acaa07d793de4e6d5e5c94eee8", 16);  
    139.         BigInteger x2 = new BigInteger(  
    140.                 "289070fb05d38ff58321f2e800536d538ccdaa3d9", 16);  
    141.   
    142.         ECPoint g = new ECPoint(x1, x2);  
    143.   
    144.         // the order of generator  
    145.         BigInteger n = new BigInteger(  
    146.                 "5846006549323611672814741753598448348329118574063", 10);  
    147.         // the cofactor  
    148.         int h = 2;  
    149.         int m = 163;  
    150.         int[] ks = { 7, 6, 3 };  
    151.         ECFieldF2m ecField = new ECFieldF2m(m, ks);  
    152.         // y^2+xy=x^3+x^2+1  
    153.         BigInteger a = new BigInteger("1", 2);  
    154.         BigInteger b = new BigInteger("1", 2);  
    155.   
    156.         EllipticCurve ellipticCurve = new EllipticCurve(ecField, a, b);  
    157.   
    158.         ECParameterSpec ecParameterSpec = new ECParameterSpec(ellipticCurve, g,  
    159.                 n, h);  
    160.         // 公钥  
    161.         ECPublicKey publicKey = new ECPublicKeyImpl(g, ecParameterSpec);  
    162.   
    163.         BigInteger s = new BigInteger(  
    164.                 "1234006549323611672814741753598448348329118574063", 10);  
    165.         // 私钥  
    166.         ECPrivateKey privateKey = new ECPrivateKeyImpl(s, ecParameterSpec);  
    167.   
    168.         Map<String, Object> keyMap = new HashMap<String, Object>(2);  
    169.   
    170.         keyMap.put(PUBLIC_KEY, publicKey);  
    171.         keyMap.put(PRIVATE_KEY, privateKey);  
    172.   
    173.         return keyMap;  
    174.     }  
    175.   
    176. }  



        请注意上述代码中的TODO内容,再次提醒注意,Chipher不支持EC算法 ,以上代码仅供参考。Chipher、Signature、KeyPairGenerator、KeyAgreement、SecretKey均不支持EC算法。为了确保程序能够正常执行,我们使用了NullCipher类,验证程序。

    照旧提供一个测试类:

    Java代码  收藏代码
    1. import static org.junit.Assert.*;  
    2.   
    3. import java.math.BigInteger;  
    4. import java.security.spec.ECFieldF2m;  
    5. import java.security.spec.ECParameterSpec;  
    6. import java.security.spec.ECPoint;  
    7. import java.security.spec.ECPrivateKeySpec;  
    8. import java.security.spec.ECPublicKeySpec;  
    9. import java.security.spec.EllipticCurve;  
    10. import java.util.Map;  
    11.   
    12. import org.junit.Test;  
    13.   
    14. /** 
    15.  *  
    16.  * @author 梁栋 
    17.  * @version 1.0 
    18.  * @since 1.0 
    19.  */  
    20. public class ECCCoderTest {  
    21.   
    22.     @Test  
    23.     public void test() throws Exception {  
    24.         String inputStr = "abc";  
    25.         byte[] data = inputStr.getBytes();  
    26.   
    27.         Map<String, Object> keyMap = ECCCoder.initKey();  
    28.   
    29.         String publicKey = ECCCoder.getPublicKey(keyMap);  
    30.         String privateKey = ECCCoder.getPrivateKey(keyMap);  
    31.         System.err.println("公钥:  " + publicKey);  
    32.         System.err.println("私钥:  " + privateKey);  
    33.   
    34.         byte[] encodedData = ECCCoder.encrypt(data, publicKey);  
    35.   
    36.         byte[] decodedData = ECCCoder.decrypt(encodedData, privateKey);  
    37.   
    38.         String outputStr = new String(decodedData);  
    39.         System.err.println("加密前: " + inputStr + " " + "解密后: " + outputStr);  
    40.         assertEquals(inputStr, outputStr);  
    41.     }  
    42. }  



    控制台输出:

    Console代码  收藏代码
      1. 公钥:   
      2. MEAwEAYHKoZIzj0CAQYFK4EEAAEDLAAEAv4TwFN7vBGsqgfXk95ObV5clO7oAokHD7BdOP9YMh8u  
      3. gAU21TjM2qPZ  
      4.   
      5. 私钥:   
      6. MDICAQAwEAYHKoZIzj0CAQYFK4EEAAEEGzAZAgEBBBTYJsR3BN7TFw7JHcAHFkwNmfil7w==  
      7.   
      8. 加密前: abc  
      9.   
      10. 解密后: abc  
  • 相关阅读:
    Linux进程管理
    GitHub
    MySQL存储过程
    MySQL自定义函数
    MySQL运算符和内置函数
    js类型检测
    防止SQL注入的方法
    PDO数据库抽象层
    PHP操作MySQL的常用函数
    第二周
  • 原文地址:https://www.cnblogs.com/kabi/p/6232932.html
Copyright © 2011-2022 走看看