博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java-信息安全(十一)-非对称加密算法ECC
阅读量:5371 次
发布时间:2019-06-15

本文共 9320 字,大约阅读时间需要 31 分钟。

概述

信息安全基本概念:

  • ECC算法(Elliptic curve cryptography,椭圆曲线密码学

ECC

  椭圆加密算法()是一种,最初由Koblitz和Miller两人于1985年提出,其数学基础是利用椭圆曲线上的构成Abel加法群上椭圆的计算困难性。

  是目前已知的公钥体制中,对每比特所提供加密强度最高的一种体制。在软件注册保护方面起到很大的作用,一般的序列号通常由该算法产生。

  ECC算法在jdk1.5后加入支持,目前仅仅只能完成密钥的生成与解析。 如果想要获得ECC算法实现,需要调用硬件完成加密/解密(ECC算法相当耗费资源,如果单纯使用CPU进行加密/解密,效率低下).

算法分类信息:

 

算法 密钥长度 默认长度 签名长度 实现的方
NONEwithECDSA 112-571 256 128 JDK/BC
RIPEMD160withECDSA 同上 256 160 BC
SHA1withECDSA ... 256 160 JDK/BC
SHA224withECDSA ... 256 224 BC
SHA256withECDSA ... 256 256 JDK/BC
SHA384withECDSA ... 256 384 JDK/BC
SHA512withECDSA ... 256 512 JDK/BC

签名示例

import java.security.KeyFactory;  import java.security.KeyPair;  import java.security.KeyPairGenerator;  import java.security.PrivateKey;  import java.security.PublicKey;  import java.security.Signature;  import java.security.interfaces.ECPrivateKey;  import java.security.interfaces.ECPublicKey;  import java.security.spec.PKCS8EncodedKeySpec;  import java.security.spec.X509EncodedKeySpec;    import com.sun.org.apache.xerces.internal.impl.dv.util.HexBin;    public class ECDSA {      private static String src = "ecdsa security";      public static void main(String[] args) {          jdkECDSA();      }            public static void jdkECDSA(){          try {              //1.初始化密钥               KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC");              keyPairGenerator.initialize(256);              KeyPair keyPair = keyPairGenerator.generateKeyPair();              ECPublicKey ecPublicKey = (ECPublicKey)keyPair.getPublic();              ECPrivateKey ecPrivateKey = (ECPrivateKey)keyPair.getPrivate();                                          //2.执行签名              PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(ecPrivateKey.getEncoded());                            KeyFactory keyFactory = KeyFactory.getInstance("EC");              PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);              Signature signature = Signature.getInstance("SHA1withECDSA");              signature.initSign(privateKey);              signature.update(src.getBytes());              byte[] res = signature.sign();              System.out.println("签名:"+HexBin.encode(res));                            //3.验证签名              X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(ecPublicKey.getEncoded());              keyFactory = KeyFactory.getInstance("EC");              PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);              signature = Signature.getInstance("SHA1withECDSA");              signature.initVerify(publicKey);              signature.update(src.getBytes());              boolean bool = signature.verify(res);              System.out.println("验证:"+bool);          } catch (Exception e) {              e.printStackTrace();          }      }    }

加解密示例代码

package com.jd.order.util.encryption;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 org.apache.commons.codec.binary.Base64;import sun.security.ec.ECKeyFactory;import sun.security.ec.ECPrivateKeyImpl;import sun.security.ec.ECPublicKeyImpl;@SuppressWarnings("restriction")public class ECCCoder {    public static final String ALGORITHM = "EC";    private static final String PUBLIC_KEY = "ECCPublicKey";    private static final String PRIVATE_KEY = "ECCPrivateKey";    /**     * 解密
* 用私钥解密 * * @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); } /** * 加密
* 用公钥加密 * * @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
keyMap) throws Exception { Key key = (Key) keyMap.get(PRIVATE_KEY); return encryptBASE64(key.getEncoded()); } /** * 取得公钥 * * @param keyMap * @return * @throws Exception */ public static String getPublicKey(Map
keyMap) throws Exception { Key key = (Key) keyMap.get(PUBLIC_KEY); return encryptBASE64(key.getEncoded()); } /** * 初始化密钥 * * @return * @throws Exception */ public static Map
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
keyMap = new HashMap
(2); keyMap.put(PUBLIC_KEY, publicKey); keyMap.put(PRIVATE_KEY, privateKey); return keyMap; } public static byte[] decryptBASE64(String data) { return Base64.decodeBase64(data); } public static String encryptBASE64(byte[] data) { return new String(Base64.encodeBase64(data)); }}

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

测试示例

package com.jd.order.util.encryption;import static org.junit.Assert.assertEquals;import java.util.Map;import org.junit.Test;public class ECCCoderTest {    @Test    public void test() throws Exception {        String inputStr = "abc";        byte[] data = inputStr.getBytes();        Map
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); }}

输出

公钥: MEAwEAYHKoZIzj0CAQYFK4EEAAEDLAAEAv4TwFN7vBGsqgfXk95ObV5clO7oAokHD7BdOP9YMh8ugAU21TjM2qPZ私钥: MDICAQAwEAYHKoZIzj0CAQYFK4EEAAEEGzAZAgEBBBTYJsR3BN7TFw7JHcAHFkwNmfil7w==加密前: abc解密后: abc

参考文档

http://snowolf.iteye.com/blog/383412

http://baike.baidu.com/item/%E6%A4%AD%E5%9C%86%E5%8A%A0%E5%AF%86%E7%AE%97%E6%B3%95/10305582?sefr=cr

转载于:https://www.cnblogs.com/guweiwei/p/8005816.html

你可能感兴趣的文章
python-flask学习
查看>>
Controller与View数据传递 多Model传递
查看>>
arm 汇编小练习
查看>>
RegQueryValueEx函数
查看>>
漫谈数据库索引
查看>>
【NOIP2004】合唱队形
查看>>
spring面试题
查看>>
python使用pickle,json等序列化dict
查看>>
php进行文件的强制下载
查看>>
每日python(6)
查看>>
Python正则表达式中的re.S的作用
查看>>
ubuntu15.10运行android studio出错unable to run mksdcard sdk tool
查看>>
HashMap面试知多少
查看>>
Effective C# 学习笔记(二十七)使你的类型可被序列化
查看>>
LDAP客户端配置
查看>>
(转)NAT原理与NAT穿越
查看>>
13.内存原理
查看>>
24.函数信号机制(本质上就是函数指针)
查看>>
The dependency `xxx` is not used in any concrete target.
查看>>
Bootstrap 中 下拉菜单和滚动监听插件(十一)(持续更新中。。。)
查看>>