RSA 1024 表示加密后的长度为 1024 位,即 128 个字节,但明文的最大长度不能超过 117 个字节,超过 117 个字节需要使用 RSA 2048,超过 245 个字节,需要使用更高位数的 RSA。
RSA 的位数越高,其密钥对产生及加密、解密的速度越慢,这是基于大素数非对称加密算法的缺陷。这样的非对称加密算法在效率上远比基于离散对数的非对称加密算法(比如:椭圆曲线加密算法)差。
Cipher rsa = Cipher.getInstance( "RSA/ECB/PKCS1Padding ");
表示,使用RSA算法,并且加PAD的方式按照PKCS1的标准。即输入数据长度小于等于密钥的位数/8-11,例如:1024位密钥,1024/8-11 =117。 不足的部分,程序会自动补气。加密后的数据还是等于密钥的位数/8。
以下是我实现的一个类:支持使用1024时加密超过117个字节的文本,并支持加密字符串为中英文。
生成公钥与私钥的类:
//*此类作用为生成密钥与公钥,密钥生成到文件中。公钥生成为字符串,可提供给他人。
public class Skey_RSA {
public static void main(String args[]) throws Exception{
KeyPairGenerator kpg=KeyPairGenerator.getInstance("RSA");
kpg.initialize(1024);
KeyPair kp=kpg.genKeyPair();
PublicKey pbkey=kp.getPublic();
PrivateKey prkey=kp.getPrivate();
FileOutputStream f2=new FileOutputStream("C://Skey_RSA_priv.dat");
ObjectOutputStream b2=new ObjectOutputStream(f2);
b2.writeObject(prkey);
try {
//此处使用了sun.misc.BASE64Encoder。网上说不建议使用,可找到相关类替换。我太懒了。。。^_^
System.err.println("公:"+(new BASE64Encoder()).encode(pbkey.getEncoded()));
} catch (Exception e) {
e.printStackTrace();
}
}
}
加密解密类:
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;
import sun.misc.BASE64Decoder;
/**
* @author yhcui
* @version 创建时间:May 18, 2011 2:44:51 PM 类说明
* RSA加密解实实现。
* 支持加密字节长度超过117。
* 支持加密中文与英文混合。
*/
public class RSAUtils {
/**
* 算法名称
*/
private final static String RSA = "RSA";
/**
* 加密后的字节分隔长度
*/
private final static int encryptSepLength = 256;
/**
* 明文字节分隔长度
*/
private final static int plainSepLneght = 100;
private static byte[] encrypt(byte[] text, PublicKey pubRSA)
throws Exception {
Cipher cipher = Cipher.getInstance(RSA);
cipher.init(Cipher.ENCRYPT_MODE, pubRSA);
return cipher.doFinal(text);
}
public final static String encrypt(String text, PublicKey uk) {
StringBuffer sbf = new StringBuffer(200);
try {
text = URLEncoder.encode(text, "UTF-8");//用这个的原因是为了支持汉字、汉字和英文混排,解密方法中同理
byte[] plainByte = text.getBytes();
ByteArrayInputStream bays = new ByteArrayInputStream(plainByte);
byte[] readByte = new byte[plainSepLneght];
int n = 0;
//这个位置很恶心人的写了一堆,是为了支持超过117字节,我每次加密100字节。
while ((n = bays.read(readByte)) > 0) {
if (n >= plainSepLneght) {
sbf.append(byte2hex(encrypt(readByte, uk)));
} else {
byte[] tt = new byte[n];
for (int i = 0; i < n; i++) {
tt[i] = readByte[i];
}
sbf.append(byte2hex(encrypt(tt, uk)));
}
}
} catch (Exception e) {
e.printStackTrace();
}
return sbf.toString();
}
public final static String decrypt(String data, PrivateKey rk) {
String rrr = "";
StringBuffer sb = new StringBuffer(100);
try {
ByteArrayInputStream bais = new ByteArrayInputStream(
data.getBytes());
//此处之所以是 256,而不是128的原因是因为有一个16进行的转换,所以由128变为了256
byte[] readByte = new byte[256];
int n = 0;
while ((n = bais.read(readByte)) > 0) {
if (n >= encryptSepLength) {
sb.append(new String(decrypt(hex2byte(readByte), rk)));
} else {
}
}
rrr = URLDecoder.decode(sb.toString(), "UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
return rrr;
}
private static byte[] decrypt(byte[] src, PrivateKey rk) throws Exception {
Cipher cipher = Cipher.getInstance(RSA);
cipher.init(Cipher.DECRYPT_MODE, rk);
return cipher.doFinal(src);
}
public static String byte2hex(byte[] b) {
String hs = "";
String stmp = "";
for (int n = 0; n < b.length; n++) {
stmp = Integer.toHexString(b[n] & 0xFF);
if (stmp.length() == 1)
hs += ("0" + stmp);
else
hs += stmp;
}
return hs.toUpperCase();
}
public static byte[] hex2byte(byte[] b) {
if ((b.length % 2) != 0)
throw new IllegalArgumentException("长度不是偶数");
byte[] b2 = new byte[b.length / 2];
for (int n = 0; n < b.length; n += 2) {
String item = new String(b, n, 2);
b2[n / 2] = (byte) Integer.parseInt(item, 16);
}
return b2;
}
public static PrivateKey getPrivateKey() {
try {
FileInputStream f = new FileInputStream("c://Skey_RSA_priv.dat");
ObjectInputStream b = new ObjectInputStream(f);
RSAPrivateKey prk = (RSAPrivateKey) b.readObject();
return prk;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static PublicKey getPublicKey() {
try {
String publicKeyStr = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDaWmSqfTHg0xyRTtih/0Q+Lk9ve+i6+ApxD27F"
+ "u+SvKupeQ/+5Bu6SBXmpvHxcC4dqfYS/NGoJ5ZTuoh8pez6bffINVY47r8UwYMuQMxYs0n1egwYw"
+ "rB+lwYbFhcOQ2BdoXcGF5fmWf2HfauQ6qNwyc2aGDXpgBIgmT5u+rZoOmwIDAQAB";
byte[] keyBytes;
keyBytes = new BASE64Decoder().decodeBuffer(publicKeyStr);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(keySpec);
return publicKey;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static void main(String args[]) {
try {
String plaintext = "a";
System.out.println("plaintextt.getByte().length:"
+ plaintext.getBytes().length);
String cipherText = encrypt(plaintext, getPublicKey());
System.out.println("cipherText:" + cipherText);
System.err.println("cipherText lenght:" + cipherText.length());
System.err.println("cipherText byte[]:"
+ cipherText.getBytes().length);
String plainText = decrypt(cipherText, getPrivateKey());
System.out.println("orginttext:" + plaintext);
System.out.println("plainTex t:" + plainText);
} catch (Exception e) {
e.printStackTrace();
}
}
}
分享到:
相关推荐
Java RSA 加密 解密 完整代码 适合 字符 及文件加解密
java RSA加密解密
java RSA加密解密
Js Java Rsa 加密解密,具体用法请看blog,里面包含js库,java jar包,和一个别人写的可以完成加密解密的demo
JAVA也是通过包来实现加密和解密的,那么我的C++是通过OPENSSL的库来实现的。 重点来到了:RSA使用过程 1、C++随机生成一对公钥和私钥 2、JAVA用公钥给明文打包形成密文 3、C++用私钥解密密文
JAVA+RSA的DEMO工程,适合初学者学习RSA加密解密 文档参看 http://blog.csdn.net/u013400939/article/details/44490441
C# JavaRSA加密解密的交互 JAVA产生秘钥 C#加密
RSA解密加密JAVA
用JAVA实现RSA的解密和加密的算法。~亲测可以运行
rsa加密解密程序,用swt做界面,可脱离界面使用,运行RSA中的main即可
经过本人修改,简化并完善了别人的代码,使其更加的容易理解和学习! 此为一个完整的项目,...功能:服务端随机生成密钥,JS用公钥加密,服务端用私钥解密。用到的JS加密文件是从官网下载的最新版,速度快,稳定性好!
C#RSA加密与JAVA解密,实现相互通信,对字符进行加密,java解密,对密文字节进行编码
JAVA中RSA加密解密工具类
* RSA加密解密:私钥解密,公钥加密。 * RSA数字签名-俗称加签验签:私钥加签,公钥验签。 * RSA加密解密:私钥解密,公钥加密。 * RSA数字签名-俗称加签验签:私钥加签,公钥验签。 * RSA加密解密:私钥...
主要介绍了Java实现的RSA加密解密算法,结合实例形式分析了java RAS加密解密算法的相关实现技巧,需要的朋友可以参考下
综合网上javasript和java RSA加密解密资源,实现了java和javascript RSA加密解密的互操作,都可以生成公钥传给对方加密然后回传密文用自己的私钥解密。
RSA加密算法实现以及C#与java互通加解密,解决RSA算法在java与C#相互通用
C#与java平台RSA加密解密签名验签互通案例,解决RSA在C#与java加密算法不同导致验签不过情况
1.java-RSA加密解密 2.java-zip加密压缩 3.js数据加密MD5 SHA1 RSA 里面都有使用方法和jar包、js,
由于Java的RSA加解密一般都是用RSA/ECB/PKCS1PADDING,导致Python一般的RSA加密库的加解密结果与Java的不兼容,Python下目前能与之兼容的RSA的库目前发现的只有一个,就是m2crypto。 这个库目前的问题是在windows...