JavaWeb RSA加密使用小解
来源:互联网 发布:淘宝怎么能分期付款 编辑:程序博客网 时间:2024/06/01 23:48
1. RSA密文和密钥
不管明文长度是多少,RSA 生成的密文长度总是固定的。
但是明文长度不能超过密钥长度。比如 Java 默认的 RSA 加密实现不允许明文长度超过密钥长度减去 11(单位是字节,也就是 byte)。也就是说,如果我们定义的密钥(我们可以通过 java.security.KeyPairGenerator.initialize(int keysize) 来定义密钥长度)长度为 1024(单位是位,也就是 bit),生成的密钥长度就是 1024位 / 8位/字节 = 128字节,那么我们需要加密的明文长度不能超过 128字节 -
11 字节 = 117字节。也就是说,我们最大能将 117 字节长度的明文进行加密,否则会出问题(抛诸如 javax.crypto.IllegalBlockSizeException:Data must not be longer than 53 bytes 的异常)。
2. Java端
String modulus = publicKey.getModulus().toString(16);
String pubexp =publicKey.getPublicExponent().toString(16);
String priexp =privateKey.getPrivateExponent().toString(16);
注意需要使用16进制下发到客户端
package com.inphase.demo.utils;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
importjava.security.NoSuchAlgorithmException;
import java.security.Security;
importjava.security.interfaces.RSAPrivateKey;
importjava.security.interfaces.RSAPublicKey;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.util.HashMap;
import javax.crypto.Cipher;
importorg.bouncycastle.jce.provider.BouncyCastleProvider;
public class RSAUtils {
/**
* 加密算法RSA
*/
publicstatic final String KEY_ALGORITHM = "RSA";
/**
* 签名算法
*/
public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
/**
* 生成公钥和私钥
*
* @throws NoSuchAlgorithmException
*
*/
publicstatic HashMap<String, Object> getKeys()
throwsNoSuchAlgorithmException {
Security.addProvider(newBouncyCastleProvider());
HashMap<String,Object> map = new HashMap<String, Object>();
KeyPairGeneratorkeyPairGen = KeyPairGenerator.getInstance("RSA",
newBouncyCastleProvider());
keyPairGen.initialize(1024);
KeyPairkeyPair = keyPairGen.generateKeyPair();
RSAPublicKeypublicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKeyprivateKey = (RSAPrivateKey) keyPair.getPrivate();
map.put("public",publicKey);
map.put("private",privateKey);
returnmap;
}
/**
* 使用模和指数生成RSA公钥
*
* @param modulus
* 模
* @param exponent
* 指数
* @return
*/
publicstatic RSAPublicKey getPublicKey(String modulus, String exponent) {
Security.addProvider(newBouncyCastleProvider());
try{
BigIntegerb1 = new BigInteger(modulus);
BigIntegerb2 = new BigInteger(exponent);
KeyFactorykeyFactory = KeyFactory.getInstance("RSA",
newBouncyCastleProvider());
RSAPublicKeySpeckeySpec = new RSAPublicKeySpec(b1, b2);
return(RSAPublicKey) keyFactory.generatePublic(keySpec);
}catch (Exception e) {
e.printStackTrace();
returnnull;
}
}
/**
* 使用模和指数生成RSA私钥 /None/NoPadding
*
* @param modulus
* 模
* @param exponent
* 指数
* @return
*/
publicstatic RSAPrivateKey getPrivateKey(String modulus, String exponent) {
try{
Security.addProvider(newBouncyCastleProvider());
BigIntegerb1 = new BigInteger(modulus);
BigInteger b2 = new BigInteger(exponent);
KeyFactorykeyFactory = KeyFactory.getInstance("RSA",
newBouncyCastleProvider());
RSAPrivateKeySpeckeySpec = new RSAPrivateKeySpec(b1, b2);
return(RSAPrivateKey) keyFactory.generatePrivate(keySpec);
}catch (Exception e) {
e.printStackTrace();
returnnull;
}
}
/**
* 公钥加密
*
* @param data
* @param publicKey
* @return
* @throws Exception
*/
publicstatic String encryptByPublicKey(String data, RSAPublicKey publicKey)
throwsException {
Security.addProvider(newBouncyCastleProvider());
Ciphercipher = Cipher.getInstance("RSA", new BouncyCastleProvider());
cipher.init(Cipher.ENCRYPT_MODE,publicKey);
//模长
intkey_len = publicKey.getModulus().bitLength() / 8;
// 加密数据长度 <= 模长-11
String[]datas = splitString(data, key_len - 11);
Stringmi = "";
//如果明文长度大于模长-11则要分组加密
for(String s : datas) {
mi+= bcd2Str(cipher.doFinal(s.getBytes()));
}
returnmi;
}
/**
* 私钥解密
*
* @param data
* @param privateKey
* @return
* @throws Exception
*/
publicstatic String decryptByPrivateKey(String data,
RSAPrivateKeyprivateKey) throws Exception {
Security.addProvider(newBouncyCastleProvider());
Ciphercipher = Cipher.getInstance("RSA", new BouncyCastleProvider());
cipher.init(Cipher.DECRYPT_MODE,privateKey);
//模长
intkey_len = privateKey.getModulus().bitLength() / 8;
byte[]bytes = data.getBytes();
byte[]bcd = ASCII_To_BCD(bytes, bytes.length);
//System.err.println(bcd.length);
//如果密文长度大于模长则要分组解密
Stringming = "";
byte[][]arrays = splitArray(bcd, key_len);
try{
for(byte[] arr : arrays) {
ming+= new String(cipher.doFinal(arr));
}
}catch (Exception e) {
e.printStackTrace();
}
returnming;
}
/**
* ASCII码转BCD码
*
*/
publicstatic byte[] ASCII_To_BCD(byte[] ascii, int asc_len) {
byte[]bcd = new byte[asc_len / 2];
intj = 0;
for(int i = 0; i < (asc_len + 1) / 2; i++) {
bcd[i]= asc_to_bcd(ascii[j++]);
bcd[i]= (byte) (((j >= asc_len) ? 0x00 : asc_to_bcd(ascii[j++])) + (bcd[i]<< 4));
}
returnbcd;
}
publicstatic byte asc_to_bcd(byte asc) {
bytebcd;
if((asc >= '0') && (asc <= '9'))
bcd= (byte) (asc - '0');
elseif ((asc >= 'A') && (asc <= 'F'))
bcd= (byte) (asc - 'A' + 10);
elseif ((asc >= 'a') && (asc <= 'f'))
bcd= (byte) (asc - 'a' + 10);
else
bcd= (byte) (asc - 48);
returnbcd;
}
/**
* BCD转字符串
*/
publicstatic String bcd2Str(byte[] bytes) {
chartemp[] = new char[bytes.length * 2], val;
for(int i = 0; i < bytes.length; i++) {
val= (char) (((bytes[i] & 0xf0) >> 4) & 0x0f);
temp[i* 2] = (char) (val > 9 ? val + 'A' - 10 : val + '0');
val= (char) (bytes[i] & 0x0f);
temp[i* 2 + 1] = (char) (val > 9 ? val + 'A' - 10 : val + '0');
}
returnnew String(temp);
}
/**
* 拆分字符串
*/
publicstatic String[] splitString(String string, int len) {
intx = string.length() / len;
inty = string.length() % len;
intz = 0;
if(y != 0) {
z= 1;
}
String[]strings = new String[x + z];
Stringstr = "";
for(int i = 0; i < x + z; i++) {
if(i == x + z - 1 && y != 0) {
str= string.substring(i * len, i * len + y);
}else {
str= string.substring(i * len, i * len + len);
}
strings[i] = str;
}
returnstrings;
}
/**
* 拆分数组
*/
publicstatic byte[][] splitArray(byte[] data, int len) {
intx = data.length / len;
inty = data.length % len;
intz = 0;
if(y != 0) {
z= 1;
}
byte[][]arrays = new byte[x + z][];
byte[]arr;
for(int i = 0; i < x + z; i++) {
arr= new byte[len];
if(i == x + z - 1 && y != 0) {
System.arraycopy(data,i * len, arr, 0, y);
}else {
System.arraycopy(data,i * len, arr, 0, len);
}
arrays[i]= arr;
}
returnarrays;
}
}
需要引入jar
3. jsp页面
<scripttype="text/javascript" src="<%=basePath%>js/jquery.min.js"></script>
<script type="text/javascript"src="<%=basePath%>js/BigInt.js"></script>
<script type="text/javascript"src="<%=basePath%>js/Barrett.js"></script>
<script type="text/javascript"src="<%=basePath%>js/RSA.js"></script>
var key =RSAUtils.getKeyPair(publicexp,privateexp,moudel);
axes = axes.split("").reverse().join("");
returnRSAUtils.encryptedString(key,data);
- JavaWeb RSA加密使用小解
- 安卓RSA加密,适配javaweb
- ios 安卓 javaweb RSA加密解密
- ios 安卓 javaweb RSA加密解密
- 使用非对称RSA加密
- 使用RSA算法加密数据
- android RSA加密的使用
- iOS中使用RSA加密
- iOS中使用RSA加密
- 使用RSA证书加密敏感数据
- iOS中使用RSA加密
- iOS中使用RSA加密
- iOS中使用RSA加密
- rsa加密使用过程小结
- .NET使用RSA加密解密
- 使用cryptography进行RSA加密
- iOS中使用RSA加密
- RSA加密解密的使用!
- Spring Boot 电子书
- HDU3790
- 获取页面上所有的checkbox选中项的value,jQuery获取checkbox选中项等操作及注意事项
- 坚持#第167天~辛德勒、珍惜
- SLF改造计划(三分枚举)(AOJ 853)
- JavaWeb RSA加密使用小解
- jquery选择器中两个class是什么意思?
- Class Throwable
- MyBatis 3 电子书
- POJ1330(LCA离线和在线)
- Java字符串类
- [Lpp] HTTP协议状态码详解(HTTP Status Code)
- 左程云著算法与数据结构题目最优解笔记-链表
- Centos修改镜像为国内的阿里云源或者163源等国内源