package com.ice.webos.util.security;

 import java.math.BigInteger;
import java.security.Key;
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.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map; import javax.crypto.Cipher; /**
* RSA 这种算法1978年就出现了,它是第一个既能用于数据加密也能用于数字签名的算法。<br>
* RSA同时有两把钥匙,公钥与私钥。同时支持数字签名。<br>
* 数字签名的意义在于,对传输过来的数据进行校验。确保数据在传输过程中不被修改。
* <ul>
* 流程分析:
* <li>甲方构建密钥对儿,将公钥公布给乙方,将私钥保留。</li>
* <li>甲方使用私钥加密数据,然后用私钥对加密后的数据签名,发送给乙方签名以及加密后的数据;乙方使用公钥、签名来验证待解密数据是否有效,如果有效使用公钥对数据解密。</li>
* <li>乙方使用公钥加密数据,向甲方发送经过加密后的数据;甲方获得加密数据,通过私钥解密。 </li>
* <ul>
*
* @author Ice_Liu
*
*/
public class RSACryptUtil {
public static final String KEY_ALGORITHM = "RSA";
public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
private static final String PUBLIC_KEY = "RSAPublicKey";
private static final String PRIVATE_KEY = "RSAPrivateKey"; /**
* 用私钥对信息生成数字签名
*
* @param data
* 加密数据
* @param privateKey
* 私钥
*
* @return
* @throws Exception
*/
public static String sign(byte[] data, String privateKey) throws Exception {
// 解密由base64编码的私钥
byte[] keyBytes = CryptUtil.decryptBASE64(privateKey);
// 构造PKCS8EncodedKeySpec对象
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
// KEY_ALGORITHM 指定的加密算法
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
// 取私钥匙对象
PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
// 用私钥对信息生成数字签名
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initSign(priKey);
signature.update(data);
return CryptUtil.encryptBASE64(signature.sign());
} /**
* 校验数字签名
*
* @param data
* 加密数据
* @param publicKey
* 公钥
* @param sign
* 数字签名
*
* @return 校验成功返回true 失败返回false
* @throws Exception
*
*/
public static boolean verify(byte[] data, String publicKey, String sign) throws Exception {
// 解密由base64编码的公钥
byte[] keyBytes = CryptUtil.decryptBASE64(publicKey);
// 构造X509EncodedKeySpec对象
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
// KEY_ALGORITHM 指定的加密算法
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
// 取公钥匙对象
PublicKey pubKey = keyFactory.generatePublic(keySpec);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initVerify(pubKey);
signature.update(data);
// 验证签名是否正常
return signature.verify(CryptUtil.decryptBASE64(sign));
} /**
* 解密<br>
* 用私钥解密
*
* @param data
* @param key
* @return
* @throws Exception
*/
public static byte[] decryptByPrivateKey(byte[] data, String key) throws Exception {
// 对密钥解密
byte[] keyBytes = CryptUtil.decryptBASE64(key);
// 取得私钥
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
// 对数据解密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(data);
} /**
* 解密<br>
* 用私钥解密
*
* @param data
* @param key
* @return
* @throws Exception
*/
public static byte[] decryptByPublicKey(byte[] data, String key) throws Exception {
// 对密钥解密
byte[] keyBytes = CryptUtil.decryptBASE64(key);
// 取得公钥
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicKey = keyFactory.generatePublic(x509KeySpec);
// 对数据解密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, publicKey);
return cipher.doFinal(data);
} /**
* 加密<br>
* 用公钥加密
*
* @param data
* @param key
* @return
* @throws Exception
*/
public static byte[] encryptByPublicKey(byte[] data, String key) throws Exception {
// 对公钥解密
byte[] keyBytes = CryptUtil.decryptBASE64(key);
// 取得公钥
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicKey = keyFactory.generatePublic(x509KeySpec);
// 对数据加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(data);
} /**
* 加密<br>
* 用私钥加密
*
* @param data
* @param key
* @return
* @throws Exception
*/
public static byte[] encryptByPrivateKey(byte[] data, String key) throws Exception {
// 对密钥解密
byte[] keyBytes = CryptUtil.decryptBASE64(key);
// 取得私钥
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
// 对数据加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
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 CryptUtil.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 CryptUtil.encryptBASE64(key.getEncoded());
} /**
* 初始化密钥
*
* @return
* @throws Exception
*/
public static Map<String, Object> initKey() throws Exception {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
keyPairGen.initialize(1024);
KeyPair keyPair = keyPairGen.generateKeyPair();
// 公钥
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
// 私钥
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
Map<String, Object> keyMap = new HashMap<String, Object>(2);
keyMap.put(PUBLIC_KEY, publicKey);
keyMap.put(PRIVATE_KEY, privateKey);
return keyMap;
} /**
* @param args
*/
public static void main(String[] args) {
try {
PBECryptUtil.main(args);
System.out.println("****************************************");
System.out.println("=====RSA加密与解密=====");
// 初始化公钥,私钥
Map<String, Object> keyMap = initKey();
String publicKey = RSACryptUtil.getPublicKey(keyMap);
String privateKey = RSACryptUtil.getPrivateKey(keyMap);
System.out.println("公钥: \n\r" + publicKey);
System.out.println("私钥: \n\r" + privateKey);
System.out.println("公钥加密——私钥解密");
String inputStr = "阿伯才的覆盖";
byte[] data = inputStr.getBytes("UTF-8");
// 公钥加密
byte[] encodedData = RSACryptUtil.encryptByPublicKey(data, publicKey);
System.out.println("公钥加密后:" + new BigInteger(encodedData).toString(32));
// 私钥解密
byte[] decodedData = RSACryptUtil.decryptByPrivateKey(encodedData, privateKey);
String outputStr = new String(decodedData, "UTF-8");
System.out.println("加密前: " + inputStr);
System.out.println("解密后: " + outputStr); System.out.println("私钥加密——公钥解密");
// 私钥加密
encodedData = RSACryptUtil.encryptByPrivateKey(data, privateKey);
System.out.println("私钥加密后:" + new BigInteger(encodedData).toString(32));
// 公钥解密
decodedData = RSACryptUtil.decryptByPublicKey(encodedData, publicKey);
outputStr = new String(decodedData, "UTF-8");
System.out.println("加密前: " + inputStr);
System.out.println("解密后: " + outputStr); System.out.println("私钥签名——公钥验证签名");
// 使用私钥产生签名
String sign = RSACryptUtil.sign(encodedData, privateKey);
System.out.println("签名:" + sign);
// 使用公匙验证签名
boolean status = RSACryptUtil.verify(encodedData, publicKey, sign);
System.err.println("验证签名结果:" + status);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} } }

转自:http://www.cnblogs.com/liubin0509/archive/2012/01/29/2331075.html

RSA 数据加密和数字签名算法的更多相关文章

  1. 第十四章 数字签名算法--RSA

    注意:本节内容主要参考自 <Java加密与解密的艺术(第2版)>第9章“带密钥的消息摘要算法--数字签名算法” <大型分布式网站架构(设计与实践)>第3章“互联网安全架构” 1 ...

  2. Java数字签名算法--RSA

    签名具有的特性: 安全性 抗否认性 数字签名:带有密钥(公钥.私钥)的消息摘要算法(使用私钥进行签名,使用公钥进行验证) 数字签名算法:RSA.DSA.ECDSA 数字签名特性: 验证数据完整性 认证 ...

  3. 数字签名算法rsa

    数字签名算法消息传递模型 由消息发送方构建密钥对,这里由甲方完成. 由消息发送方公布公钥至消息接收方,这里由甲方将公钥公布给乙方. 注意如加密算法区别,这里甲方使用私钥对数据签名,数据与签名形成一则消 ...

  4. ECDSA数字签名算法

    一.ECDSA概述 椭圆曲线数字签名算法(ECDSA)是使用椭圆曲线密码(ECC)对数字签名算法(DSA)的模拟.ECDSA于1999年成为ANSI标准,并于2000年成为IEEE和NIST标准.它在 ...

  5. JAVA加解密 -- 数字签名算法

    数字签名 – 带有密钥的消息摘要算法 作用:验证数据完整性.认证数据来源.抗否认(OSI参考模型) 私钥签名,公钥验证 RSA 包含非对称算法和数字签名算法 实现代码: //1.初始化密钥 KeyPa ...

  6. .NET Core加解密实战系列之——消息摘要与数字签名算法

    目录 简介 功能依赖 消息摘要算法 MD算法 家族发展史 应用场景 代码实现 MD5 示例代码 SHA算法 应用场景 代码实现 SHA1 SHA256 示例代码 MAC算法 HMAC算法的典型应用 H ...

  7. Windows phone应用开发[19]-RSA数据加密

    在这个系列的第十六章节中Windows phone应用开发[16]-数据加密 中曾详细讲解过windows phone 常用的MD5,HMAC_MD5,DES,TripleDES[3DES] 数据加密 ...

  8. RSA/SHA1加密和数字签名算法在开放平台中的应用

    加密算法 加密算法分为两大类:1.对称加密算法:2.非对称加密算法.   密钥个数 加密 解密 对称加密 一个 使用密钥加密 使用同一个密钥解密 非对称加密 两个,公钥和私钥 使用其中一把密钥加密 使 ...

  9. java数字签名算法之RSA

    © 版权声明:本文为博主原创文章,转载请注明出处 实例 1.项目结构 2.pom.xml <project xmlns="http://maven.apache.org/POM/4.0 ...

随机推荐

  1. Ajax实现文件的上传

    Ajax实现文件的上传 准备 ajax的参数补充 type不写的话默认是GET dataType和ContentType: dataType: 浏览器发给服务器希望返回的数据类型 .. 如果明确地指定 ...

  2. flask 三剑客

    1.flask中的httpresponse @app.route("/") # app中的route装饰器 def index(): # 视图函数 return "Hel ...

  3. 涨知识 --- VI

    1.空类所占空间大小 空类所占空间为1,单一继承的空类空间也为1,多继承的空类空间还是1.但是虚继承涉及虚表(虚指针),所以sizeof(C)的大小为4. 2.内联函数与宏定义 Ans:内联函数和普通 ...

  4. [ NOIP 2014 ] TG

    \(\\\) \(Day\ 1\) \(\\\) \(\#\ A\) \(Rps\) 定义五种方案的石头剪刀布游戏,两人共进行\(N\)局游戏,已知两人各自的循环节和具体方案,胜者得\(1\)分,败者 ...

  5. CF126B Password

    思路: kmp略作修改. 实现: #include <iostream> #include <cstdio> using namespace std; ; int neXt[M ...

  6. jQuery——stop

    为什么要停止动画? 对同一个元素,如果拥有一个以上的动画对其加以作用,那么后面的动画会被放入一个动画队列中.动画队列的动画是在其上一个动画完成以后才会执行. 控制两个参数四种情况 1.第一个参数表示后 ...

  7. vim之补全2(完全个人定制版)

    关于补全的方面要说的的确很多, 这里选择分为两个章叙述. 如果你想学vim, 你需要有很强的耐心, 如果你想锻炼这种耐心, 你可以试着先看完我之前的文章. 好了, 下面继续我们的vim补全吧. vim ...

  8. 用sed替换含反斜(\)的字符串

    今天在linux替换配置文件时,test文件里有一个字符串 e:\ 需要换成/usr/home/ 用了sed命令:sed -i "s?e:\\?/usr/home/?g" test ...

  9. C 语言常用方法技巧

    C语言常用方法技巧 *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !impor ...

  10. 查找java文件

    想要在eclipse里找一个类文件,可以用快捷键CTRL + SHIFT + R,但是有些文件是jar包里的类文件,可以用下图方法,创建一个变量,然后按住CTRL键,点击类名称 这样就找到jar文件了