ECC加密算法 java

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

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

通过java代码实现如下:Coder类见

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
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 梁栋
  * @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 = {  7 6 3  };
         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 );
         // 私钥
         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类,验证程序。

照旧提供一个测试类:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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 梁栋
  * @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

    本篇的主要内容为Java证书体系的实现。 

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值