概述

信息安全基本概念:

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

ECC

  椭圆加密算法(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"; /**
* 解密<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;
} 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<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);
} }

输出

公钥:
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

java-信息安全(十一)-非对称加密算法ECC的更多相关文章

  1. java-信息安全(十一)-非对称加密算法ECC以及ECDSA签名

    概述 信息安全基本概念: ECC算法(Elliptic curve cryptography,椭圆曲线密码学) 一.ECC加密解密[暂时无意义] 椭圆加密算法(ECC)是一种公钥加密体制,最初由Kob ...

  2. Java 加密解密 对称加密算法 非对称加密算法 MD5 BASE64 AES RSA

    版权声明:本文为博主原创文章,未经博主允许不得转载. [前言] 本文简单的介绍了加密技术相关概念,最后总结了java中现有的加密技术以及使用方法和例子 [最简单的加密] 1.简单的概念 明文:加密前的 ...

  3. 【Java】聊聊常用的非对称加密算法之一RSA的使用(Java)

    参考的优秀文章 Java加密技术(四)——非对称加密算法RSA RSA算法原理(一).RSA算法原理(二) RSA的公钥和私钥到底哪个才是用来加密和哪个用来解密? 简单的介绍 RSA是有名的非对称加密 ...

  4. Java进阶(七)Java加密技术之非对称加密算法RSA

    Java加密技术(四)--非对称加密算法RSA 非对称加密算法--RSA 基本概念 非对称加密算法是一种密钥的保密方法. 非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥(priv ...

  5. 第十一章 非对称加密算法--DH

    注意:本节内容主要参考自<Java加密与解密的艺术(第2版)>第8章“高等加密算法--非对称加密算法” 11.1.非对称加密算法 特点: 发送方和接收方均有一个密钥对(公钥+私钥),其中公 ...

  6. JAVA 非对称加密算法RSA

    非对称加密算法 RSA过程 : 以甲乙双方为例 1.初始化密钥 构建密钥对,生成公钥.私钥保存到keymap中 KeyPairGenerator ---> KeyPair --> RSAP ...

  7. Java加密技术(四)非对称加密算法RSA

    RSA      这样的算法1978年就出现了.它是第一个既能用于数据加密也能用于数字签名的算法.它易于理解和操作.也非常流行.算法的名字以发明者的名字命名:Ron Rivest, AdiShamir ...

  8. JAVA加解密 -- 对称加密算法与非对称加密算法

    对称加密算法:双方必须约定好算法 DES 数据加密标准:由于不断地被破解 自98年起就已经逐渐放弃使用 AES 目前使用最多的加密方式,官方并未公布加密方式已被破解,替代DES 实现和DES非常接近 ...

  9. JAVA实现RSA加密,非对称加密算法

    RSA.java package org.icesnow.jeasywx.util.security; import java.security.Key; import java.security.K ...

随机推荐

  1. ssm中从页面到controller和数据库出现乱码问题的解决

    1.确保项目编码为utf8,点击项目右键,点击properties 2.确保数据库编码为utf8,以MySQL为例,可到mysql目录下,my.ini文件中修改后,重启mysql服务 重启mysql服 ...

  2. Redis简单延时队列

    Redis实现简单延队列, 利用zset有序的数据结构, score设置为延时的时间戳. 实现思路: 1.使用命令 [zrangebyscore keyName socreMin socreMax] ...

  3. 增益 Gain 分贝 dB

    https://zh.wikipedia.org/wiki/%E5%88%86%E8%B2%9D 分贝(decibel)是量度两个相同单位之数量比例的单位,主要用于度量声音强度,常用dB表示. “分” ...

  4. C#轻量级日志监控器EasyLogMonitor

    一.课程介绍 本次分享课程属于<C#高级编程实战技能开发宝典课程系列>中的一部分,阿笨后续会计划将实际项目中的一些比较实用的关于C#高级编程的技巧分享出来给大家进行学习,不断的收集.整理和 ...

  5. delphi中接口的委托和聚合

    Delphi的TRegistry注册表类 方法详解 Delphi的接口编程入门 delphi中接口的委托和聚合 2009-09-27 10:44:44|  分类: 默认分类 |  标签: |举报 |字 ...

  6. js 获取浏览器/网页宽度高度整理

    网页宽度.高度: 网页可见区域宽: document.body.clientWidth 网页可见区域高: document.body.clientHeight 网页可见区域宽: document.bo ...

  7. Java断言绝对不是鸡肋

    在防御式编程中经常会用断言(Assertion)对参数和环境做出判断,避免程序因不当的输入或错误的环境而产生逻辑异常,断言在很多语言中都存在,C.C++.Python 都有不同的断言表示形式.在Jav ...

  8. javascript数据类型的判断

    最近看到了很多关于数据类型判断的方法,总结了下 一.javascript的数据类型 js数据分为两种类型:原始数据类型和引用数据类型.原始数据类型有:string.number.boolean.und ...

  9. 【T04】开发并使用应用程序框架

    1.TCP/IP应用程序分为 TCP服务器 TCP客户端 UDP服务器 UDP客户端 2.构建框架库是比较简单的一件事,主要就是对socket编程.

  10. IE10、IE11使用 __doPostBack 出现未定义问题

    在公司的老项目中分页控件使用了 __doPostBack 方式,在IE兼容模式下正常,在IE10.IE11中 __doPostBack 出现未定义问题. 百度查阅资料得知,这是微软NET环境下的一个B ...