javarsaapi的简单介绍
今天给各位分享javarsaapi的知识,其中也会对进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!
本文目录一览:
- 1、有谁有RSA的java API调用函数,高分悬赏~~
- 2、Java中RSA的方式如何实现非对称加密的示例
- 3、java rsa证书 ios 支持吗
- 4、JAVA里面RSA加密算法的使用
- 5、怎样用Java实现RSA加密
有谁有RSA的java API调用函数,高分悬赏~~
给你一个利用 JAVA RSA API 做的一个子类,删掉了很多注释,如果想要详细点的在这两天之内密我:
package common.ciphers.unsymmetry;
import java.security.*;
import javax.crypto.*;
public class RSACipher
extends UnsymmetryCipher
{
/** 签名器 */
private Signature signner;
/** 系统实现好了的密码机(用SunJCE公司的) */
protected Cipher cipher;
public RSACipher()
throws Exception
{
super( 512, "RSA" ); //默认用512位的密钥值
cipher = Cipher.getInstance( "RSA" );
}
public RSACipher( int keySize )
throws Exception
{
super( keySize, "RSA" );
cipher = Cipher.getInstance( "RSA" );
}
public byte[] doEncrypt( byte[] plainText, PublicKey myPbKey )
throws Exception
{
if( myPbKey != null )
{
cipher.init( Cipher.ENCRYPT_MODE, myPbKey );
return cipher.doFinal( plainText );
}
return null;
}
public byte[] doDecrypt( byte[] encrypted, PrivateKey myPvKey )
throws Exception
{
if( myPvKey != null )
{
cipher.init( Cipher.DECRYPT_MODE, myPvKey );
return cipher.doFinal( encrypted );
}
return null;
}
public byte[] sign( byte[] plain, PrivateKey myPvKey )
throws Exception
{
signner = Signature.getInstance( "RSA" );
signner.initSign( myPvKey );
signner.update( plain );
return signner.sign();
}
public boolean verify( byte[] plain, byte[] signed, PublicKey myPbKey )
throws
Exception
{
signner = Signature.getInstance( "RSA" );
signner.initVerify( myPbKey );
signner.update( plain );
return signner.verify( signed );
}
public String toString()
{
return "RSA 非对称密码机 Version 1.0 Made By Ren\n" + super.toString();
}
}
package common.ciphers.unsymmetry;
import common.helper.Helper;
import java.io.*;
import java.security.*;
import common.ciphers.unsymmetry.MessageDigester;
public abstract class UnsymmetryCipher
{
/** 密钥对生成器 */
protected KeyPairGenerator keyPairGenerator;
/** 密钥对 */
protected KeyPair keyPair;
/** 算法名称 */
protected final String algorithm;
/** 安全的随机源 */
private SecureRandom random;
/** 此密码机的公钥信息 */
protected PublicKey pbKey;
/** 此密码机的私钥信息 */
protected PrivateKey pvKey;
/** 此密码机的密钥位数 */
protected final int KEY_SIZE;
/**p
* =========================================================================
* p 以指定密钥位数和算法初始化此非对称密码机
* @param keySize int 密钥位数
* @param algorithm String 非对称算法名
* @throws Exception 如果系统没有安装此非对称密码机.p
=========================================================================*/
public UnsymmetryCipher(int keySize, String algorithm) throws Exception {
//使用SUN公司提供的密码机
java.security.Security.addProvider(new com.sun.crypto.provider.SunJCE());
KEY_SIZE = keySize;
this.algorithm = algorithm;
init();
}
/**p
* =========================================================================
* p 初始化 KeyPair, 公钥,私钥,和 密码机
* @throws Exception 如果系统没有安装此非对称密码机.p
=========================================================================*/
private void init() throws Exception {
keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
random = new SecureRandom();
keyPairGenerator.initialize(KEY_SIZE, random);
keyPair = keyPairGenerator.generateKeyPair();
pbKey = keyPair.getPublic();
pvKey = keyPair.getPrivate();
}
/**p
* =========================================================================
* p 用指定公钥加密指定的明文信息
* @param plain byte[] 指定的明文信息
* @param myKey PublicKey 指定的密钥
* @return byte[] 加密后的密文信息
* @throws Exception 如果加密过程出现错误.p
=========================================================================*/
protected abstract byte[] doEncrypt(byte[] plain, PublicKey myKey) throws
Exception;
/** @todo 子类实现: 用指定公钥加密此指定的明文信息 */
/**p
* =========================================================================
* p 用指定私钥解密指定的密文信息
* @param encrypted byte[] 指定的密文信息
* @param myKey PrivateKey 指定的密钥
* @return byte[] 解密后的明文信息
* @throws Exception 如果解密过程出现错误.p
=========================================================================*/
protected abstract byte[] doDecrypt(byte[] encrypted, PrivateKey myKey) throws
Exception;
/** @todo 子类实现: 用本密码机的私钥解密此指定信息 */
/**p
* =========================================================================
* p 签名算法: 用指定私钥签名指定的信息
* @param plain byte[] 指定的要签名的信息
* @param myPvKey RSAPrivateKey 指定的私钥信息
* @return byte[] 签名后的信息
* @throws Exception 签名过程出现差错.p
=========================================================================*/
protected abstract byte[] sign(byte[] plain, PrivateKey myPvKey) throws
Exception;
/** @todo 子类实现: 用指定私钥签名此指定的明文信息 */
/**p
* =========================================================================
* p 用指定的公钥解密签过名的信息
* @param plain byte[] 原明文信息
* @param signed byte[] 签过名的信息
* @param pbKey PublicKey 指定的公钥信息
* @return boolean 解密后的信息是否与明文信息相同
* @throws Exception 如果解密过程出现错误.p
=========================================================================*/
protected abstract boolean verify(byte[] plain, byte[] signed,
PublicKey pbKey) throws Exception;
/** @todo 子类实现: 用指定的公钥验证指定签名信息是否等同于所给的明文 */
/**p
* =========================================================================
* p 用此密码机的公钥加密指定明文信息
* @param plain byte[] 指定的明文信息
* @return byte[] 加密后的信息
* @throws Exception 加密过程都可能出现错误 .p
=========================================================================*/
public byte[] doEncrypt(byte[] plain) throws Exception {
return this.doEncrypt(plain, this.pbKey);
}
/**p
* =========================================================================
* p 用本密码机的私钥解密指定密文信息
* @param encrypted byte[] 指定的密文信息
* @return byte[] 解密后的明文信息
* @throws Exception 解密过程都可能出现错误 .p
=========================================================================*/
public byte[] doDecrypt(byte[] encrypted) throws Exception {
return this.doDecrypt(encrypted, this.pvKey);
}
/**p
* =========================================================================
* p 用本密码机的私钥对指定数据进行签名
* @param plain byte[] 要求签名的明文信息
* @return byte[] 签好名的密文信息
* @throws Exception 如果签名过程中出现错误.p
=========================================================================*/
public byte[] sign(byte[] plain) throws Exception {
return sign(plain, this.pvKey);
}
public boolean verify(byte[] plain, byte[] signed) throws Exception {
return verify(plain, signed, this.pbKey);
}
public PublicKey getPbKeyFromHexFile(String fileName) throws Exception {
return getPbKeyFromHexFile(new FileInputStream(fileName));
}
public PublicKey getPbKeyFromHexFile(InputStream is) throws Exception {
byte[] encodedKeyHexValue = new byte[is.available()];
is.read(encodedKeyHexValue);
String keyInHexValue = Helper.bsTpOp.bytesToCommonString(
encodedKeyHexValue);
byte[] encodedKeyRealValue = Helper.bsTpOp.strHexToBytes(keyInHexValue);
return bytesToPbKey(encodedKeyRealValue);
}
public PrivateKey getPvKeyFromHexFile(String fileName) throws Exception {
return getPvKeyFromHexFile(new FileInputStream(fileName));
}
public PrivateKey getPvKeyFromHexFile(InputStream is) throws Exception {
byte[] encodedKeyHexValue = new byte[is.available()];
is.read(encodedKeyHexValue);
String keyInHexValue = Helper.bsTpOp.bytesToCommonString(
encodedKeyHexValue);
byte[] encodedKeyRealValue = Helper.bsTpOp.strHexToBytes(keyInHexValue);
return bytesToPvKey(encodedKeyRealValue);
}
public PublicKey getPbKeyFromObjFile(String fileName) throws Exception {
return getPbKeyFromObjFile(new FileInputStream(fileName));
}
public PublicKey getPbKeyFromObjFile(InputStream fis) throws Exception {
ObjectInputStream ois = new ObjectInputStream(fis);
PublicKey pbKey = (PublicKey) ois.readObject();
ois.close();
return pbKey;
}
public PrivateKey getPvKeyFromObjFile(String fileName) throws Exception {
return getPvKeyFromObjFile(new FileInputStream(fileName));
}
public PrivateKey getPvKeyFromObjFile(InputStream fis) throws Exception {
ObjectInputStream ois = new ObjectInputStream(fis);
PrivateKey pvKey = (PrivateKey) ois.readObject();
ois.close();
return pvKey;
}
public void savePbKeyToObjFile(String fileName) throws Exception {
savePbKeyToObjFile(new FileOutputStream(fileName));
}
public void savePbKeyToObjFile(OutputStream fos) throws Exception {
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(pbKey);
oos.close();
}
public void savePvKeyToObjFile(String fileName) throws Exception {
savePvKeyToObjFile(new FileOutputStream(fileName));
}
public void savePvKeyToObjFile(OutputStream fos) throws Exception {
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(pvKey);
oos.close();
}
public void savePbKeyToHexFile(String fileName) throws Exception {
savePbKeyToHexFile(new FileOutputStream(fileName));
}
public void savePbKeyToHexFile(OutputStream fos) throws Exception {
String hexValue = Helper.bsTpOp.bytesToHexStr(getPublicKeyBytes());
fos.write(Helper.bsTpOp.strToCommonBytes(hexValue));
fos.close();
}
public void savePvKeyToHexFile(String fileName) throws Exception {
savePvKeyToHexFile(new FileOutputStream(fileName));
}
public void savePvKeyToHexFile(OutputStream fos) throws Exception {
String hexValue = Helper.bsTpOp.bytesToHexStr(getPrivateKeyBytes());
fos.write(Helper.bsTpOp.strToCommonBytes(hexValue));
fos.close();
}
public byte[] get128BitKey(PublicKey pb, PrivateKey pv) throws Exception {
MessageDigester hasher = new MessageDigester("MD5");
hasher.addMessage(pb.getEncoded());
hasher.addMessage(pv.getEncoded());
return hasher.generateDigest(); //得到128位14个字节的公私钥特征码
}
public PublicKey bytesToPbKey(byte[] encodedPbKey) throws Exception {
return bytesToPbKey(encodedPbKey, this.algorithm);
}
public PublicKey bytesToPbKey(byte[] encodedPbKey, String algorithm) throws
Exception {
java.security.spec.X509EncodedKeySpec pbKeySpec =
new java.security.spec.X509EncodedKeySpec(encodedPbKey);
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
return keyFactory.generatePublic(pbKeySpec);
}
public PrivateKey bytesToPvKey(byte[] encodedPvKey) throws Exception {
return bytesToPvKey(encodedPvKey, this.algorithm);
}
public PrivateKey bytesToPvKey(byte[] encodedPvKey, String algorithm) throws
Exception {
java.security.spec.X509EncodedKeySpec pvKeySpec =
new java.security.spec.X509EncodedKeySpec(encodedPvKey);
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
return keyFactory.generatePrivate(pvKeySpec);
}
public void setPublicKey(PublicKey publicKey) {
pbKey = publicKey;
}
public void setPrivateKey(PrivateKey privateKey) {
pvKey = privateKey;
}
public PublicKey getPublicKey() {
return pbKey;
}
public byte[] getPublicKeyBytes() {
return getPublicKey().getEncoded();
}
public PrivateKey getPrivateKey() {
return pvKey;
}
public byte[] getPrivateKeyBytes() {
return getPrivateKey().getEncoded();
}
/**p
* =========================================================================
* p 获取此密码机的密钥长度
* @return int 密钥长度信息.p
=========================================================================*/
public int getKeySize() {
return KEY_SIZE;
}
/**p
* =========================================================================
* p 算法描述
* @return String 算法描述.p
=========================================================================*/
public String toString() {
return "本非对称密码机实现之算法: " + algorithm;
}
}
Java中RSA的方式如何实现非对称加密的示例
代码如下,需要依赖一个jar包commons-codec-1.9.jar,用于Base64转换,请自行下载。
import org.apache.commons.codec.binary.Base64;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
public class RSAUtils {
// 加密方式
public static final String ALGORITHM = "RSA";
// 签名算法
private static final String SIGNATURE_ALGORITHM = "SHA1WithRSA";
// 创建密钥对初始长度
private static final int KEY_SIZE = 512;
// 字符编码格式
private static final String CHARSET = "UTF-8";
// RSA最大加密明文大小
private static final int MAX_ENCRYPT_BLOCK = 117;
// RSA最大解密密文大小
private static final int MAX_DECRYPT_BLOCK = 128;
private KeyFactory keyFactory;
public RSAUtils() throws NoSuchAlgorithmException {
keyFactory = KeyFactory.getInstance(ALGORITHM);
}
/**
* 私钥加密
*
* @param content 待加密字符串
* @param privateKey 私钥
* @return 加密后字符串(BASE64编码)
*/
public String encryptByPrivateKey(String content, String privateKey) throws Exception {
String result;
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
byte[] keyBytes = new Base64().decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
PrivateKey pKey = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, pKey);
byte[] data = content.getBytes(CHARSET);
write2Stream(cipher, data, out);
byte[] resultBytes = out.toByteArray();
result = Base64.encodeBase64String(resultBytes);
} catch (Exception e) {
throw new Exception(e);
}
return result;
}
/**
* 公钥解密
*
* @param content 已加密字符串(BASE64加密)
* @param publicKey 公钥
* @return
*/
public String decryptByPublicKey(String content, String publicKey) throws Exception {
String result = "";
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
byte[] keyBytes = new Base64().decode(publicKey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
PublicKey pKey = keyFactory.generatePublic(x509KeySpec);
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, pKey);
byte[] data = Base64.decodeBase64(content);
write2Stream(cipher, data, out);
byte[] resultBytes = out.toByteArray();
result = new String(resultBytes);
} catch (Exception e) {
throw new Exception(e);
}
return result;
}
/**
* 公钥加密
*
* @param content 待加密字符串
* @param publicKey 公钥
* @return 加密后字符串(BASE64编码)
*/
public String encryptByPublicKey(String content, String publicKey) throws Exception {
String result = "";
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
byte[] keyBytes = new Base64().decode(publicKey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
PublicKey pKey = keyFactory.generatePublic(x509KeySpec);
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, pKey);
byte[] data = content.getBytes(CHARSET);
write2Stream(cipher,
data, out);
byte[] resultBytes = out.toByteArray();
result = Base64.encodeBase64String(resultBytes);
} catch (Exception e) {
throw new Exception(e);
}
return result;
}
/**
* 私钥解密
*
* @param content 已加密字符串
* @param privateKey 私钥
* @return 解密后字符串
*/
public String decryptByPrivateKey(String content, String privateKey) throws Exception {
String result = "";
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
byte[] keyBytes = new Base64().decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
PrivateKey pKey = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, pKey);
byte[] data = Base64.decodeBase64(content);
write2Stream(cipher, data, out);
byte[] resultBytes = out.toByteArray();
result = new String(resultBytes);
} catch (Exception e) {
throw new Exception(e);
}
return result;
}
private static void write2Stream(Cipher cipher, byte[] data, ByteArrayOutputStream out) throws
BadPaddingException, IllegalBlockSizeException {
int dataLen = data.length;
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段解密
while (dataLen - offSet 0) {
if (dataLen - offSet MAX_DECRYPT_BLOCK) {
cache = cipher.doFinal(data, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offSet, dataLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_DECRYPT_BLOCK;
}
}
/**
* 用私钥对信息生成数字签名
*
* @param data 已加密数据
* @param privateKey 私钥(BASE64编码)
* @return sign
*/
public String sign(String data, String privateKey) throws Exception {
String result = "";
try {
byte[] keyBytes = new Base64().decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initSign(privateK);
signature.update(parse2HexStr(data).getBytes(CHARSET));
result = new Base64().encodeToString(signature.sign());
} catch (Exception e) {
throw new Exception(e);
}
return result;
}
/**
* 校验数字签名
*
* @param data 已加密数据
* @param publicKey 公钥(BASE64编码)
* @param sign 数字签名
* @return
* @throws Exception
*/
public boolean verify(String data, String publicKey, String sign) throws Exception {
boolean result;
try {
byte[] keyBytes = new Base64().decode(publicKey);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
PublicKey publicK = keyFactory.generatePublic(keySpec);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initVerify(publicK);
signature.update(parse2HexStr(data).getBytes(CHARSET));
result = signature.verify(new Base64().decode(sign));
} catch (Exception e) {
throw new Exception(e);
}
return result;
}
/**
* 将二进制转换成16进制
*
* @param data
* @return
*/
public static String parse2HexStr(String data) throws Exception {
String result = "";
try {
byte[] buf = data.getBytes(CHARSET);
StringBuffer sb = new StringBuffer();
for (int i = 0; i buf.length; i++) {
String hex = Integer.toHexString(buf[i] 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
sb.append(hex.toUpperCase());
}
result = sb.toString();
} catch (UnsupportedEncodingException e) {
throw new Exception(e);
}
return result;
}
/**
* 生成公钥与私钥
*/
public static void createKey() throws Exception {
try {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM);
keyPairGenerator.initialize(KEY_SIZE);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
String publicKey = Base64.encodeBase64String(rsaPublicKey.getEncoded());
String privateKey = Base64.encodeBase64String(rsaPrivateKey.getEncoded());
System.out.println("publicKey=" + publicKey + "\nprivateKey=" + privateKey);
} catch (NoSuchAlgorithmException e) {
throw new Exception(e);
}
}
public static void main(String[] args) throws Exception {
String PRIVATE_KEY = "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAKeYGXH6Vz+m+KuL11RDRaNdHB4YQeZgqpJGPRSwBelgvEoHu2/fNs1bmgfJhI8lhr/o/Hy8EFB/I/DDyLcCcU4bCLtxpki8edC+KJR2WvyYfnVmWEe/3q2jSVKRf81868q9Cd3MMfrQPMsY4x0TQ0GtOf/nMSMbAltV2W8J86IfAgMBAAECgYEApYu4lr2SMW3ddJZNvQ42W4g9nfyYG9igpJx8+VJmhIDpfLbmjzsOBwvUupx0NHH9CNQ7k3qxItJzzf+W5C+lesEOAqdO5nahRZsL8BIDoxTEn2j+1GXkzQw3vqPY50xqRnZsoP5TyNNsOM7KYaOoz4VFMdVIFwoT3OKM5z7mxgECQQD51r17WZDSa/kucaH7gCOePxJPS6Ust0eVd5tBOMpFzD/VtziogSIWyhGKkLH0SyTJEe91CCpdpxufLSZgIiN5AkEAq7ojtvU4twak1N1/1qX+t8f5wD8i/8GU702PeCwkGI5ymrARq+W2yCuvU1bouXBhjKHV4KhafKYixdHUMg00VwJAYVUjpLaUESY3gbyLWqvlNHVl8LaLtwwAO17JgXNaei7Ef8JNtHf6i95VTyJn8cCEqEDwhSuVNb8wp6azWKh0IQJBAJHrcT2d0bt0IcvfCynRk0eG3WnGPG8mhu9w8GAk4ecb47YdtmZio5YjyK8AQnCQVdOyEJL9eyY/5XxCeBSvs7ECQQCKQ2f5HLDkkHvc6rlaHCJmqNRCS+CxhoaiaSPYLAac7WXmb614ACLECc86C/nkefTq0SNpUDVbGxVpJi9/FOUf";
String PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCnmBlx+lc/pviri9dUQ0WjXRweGEHmYKqSRj0UsAXpYLxKB7tv3zbNW5oHyYSPJYa/6Px8vBBQfyPww8i3AnFOGwi7caZIvHnQviiUdlr8mH51ZlhHv96to0lSkX/NfOvKvQndzDH60DzLGOMdE0NBrTn/5zEjGwJbVdlvCfOiHwIDAQAB";
RSAUtils rsaUtil = new RSAUtils();
String encryptByPublicKey = rsaUtil.encryptByPublicKey("你好!", PUBLIC_KEY);
System.out.println(encryptByPublicKey);
String decryptByPrivateKey = rsaUtil.decryptByPrivateKey(encryptByPublicKey, PRIVATE_KEY);
System.out.println(decryptByPrivateKey);
String encryptByPrivateKey = rsaUtil.encryptByPrivateKey("你好!", PRIVATE_KEY);
System.out.println(encryptByPrivateKey);
String decryptByPublicKey = rsaUtil.decryptByPublicKey(encryptByPrivateKey, PUBLIC_KEY);
System.out.println(decryptByPublicKey);
String sign = rsaUtil.sign("1234", PRIVATE_KEY);
System.out.println("sign:" + sign);
System.out.println(rsaUtil.verify("1234", PUBLIC_KEY, sign));
}
}
java rsa证书 ios 支持吗
了之前三个终端进行AES加解密的经验,实现RSA加解密倒不是太复杂。两个关键点:1)RSA需要密钥文件,且密钥文件的格式很重要;2)padding方式需要一致,比较被广泛支持且被很多RAS实现设置为默认padding方式的是PKCS1PADDING V1.5,建议采用。
我是在linux下用openssl生成公钥、私钥文件的,分三个步骤,命令如下:
1、生成公钥public_key.der 和 私钥private_key.pem(加密)
openssl req -x509 -out public_key.der -outform der -new -newkey rsa:1024 -keyout private_key.pem
按照提示,填入私钥的密码,签名证书的组织名、邮件等信息之后,就会生成包含有公钥的证书文件public_key.der和私钥文件private_key.pem。public_key.der文件用于分发到ios客户端进行公钥加密。
2、生成公钥public_key.pem。
openssl rsa -in private_key.pem -pubout -out public_key.pem ,这步生成的public_key.pem用于分发到c++客户端和安卓客户端进行公钥加密。
3、将私钥 private_key.pem(加密)转换为PKCS#8编码格式(且不加密)。
openssl pkcs8 -topk8 -in private_key.pem -out pkcs8_private_key.pem -nocrypt
这步生成的pkcs8_private_key.pem用于在Java服务端进行私钥解密。
RSA的一般用法是在客户端用公钥加密,在网络上传输密文,然后服务端用私钥解密获取原文。所以RSA实现都会支持公钥加密、私钥解密。反过来用私钥加密然后公钥解密,理论上也是可行的。不过我没有试过。如果决定要这么做,祝君好运。
注意:RSA提供的API不像AES,不会自动分块处理。需要手动将原文切割为128-11的块去进行加密 (128是因为采用RSA1024,128=1024/8, 11是因为padding采用版本1.5的PKCS1PADDING。这种分块方式是多个RSA实现的默认方式,推荐使用),每次加密输出的密文长度均是128字节(RSA1024),把这些密文顺序拼装起来。在解密的时候,则是将密文按128字节进行切割,解密后再拼装在一起即可。
======================C++客户端公钥加密=======================
使用大名鼎鼎openssl类库实现,感慨下其API设计得真烂。。。。
注意:虽然输入和输出都是std::string,但不要理解成字符串,实际上都是二进制数据。另外公钥得保存在文件中,我还没找到使用内存中公钥的方法,但对我已经够用了。
std::string EvpHelper::rsaEncryptUsingPublicKeyFile(const std::string source, const std::string keyFile)
{
std::string result;
BIO* bp = NULL;
EVP_PKEY* key = NULL;
RSA* rsa = NULL;
EVP_PKEY_CTX* ctx = NULL;
unsigned char* encryptedData = NULL;
try
{
// load public key
OpenSSL_add_all_algorithms();
bp = BIO_new(BIO_s_file());
if (bp == NULL)
{
throw std::runtime_error("BIO_new failed.");
}
if (BIO_read_filename(bp, keyFile.c_str()) = 0)
{
throw std::runtime_error("BIO_read_filename failed.");
}
rsa = PEM_read_bio_RSA_PUBKEY(bp, NULL, NULL, NULL);
if (rsa == NULL)
{
throw std::runtime_error("PEM_read_bio_RSA_PUBKEY failed.");
}
key = EVP_PKEY_new();
if (key == NULL)
{
throw std::runtime_error("EVP_PKEY_new failed.");
}
EVP_PKEY_assign_RSA(key, rsa);
rsa = NULL;
// encrypt
OpenSSL_add_all_ciphers();
ctx = EVP_PKEY_CTX_new(key, NULL);
if (ctx == NULL)
{
throw std::runtime_error("EVP_PKEY_CTX_new failed.");
}
if (EVP_PKEY_encrypt_init(ctx) = 0)
{
throw std::runtime_error("EVP_PKEY_encrypt_init failed.");
}
if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) = 0)
{
throw std::runtime_error("EVP_PKEY_CTX_set_rsa_padding failed.");
}
encryptedData = new unsigned char[source.size() * 2];
size_t encryptedDataLen = 0;
size_t BLOCK_SIZE = 128 - 11;
size_t sourceDataLen = (int)source.size();
for (size_t i = 0; i sourceDataLen; i += BLOCK_SIZE)
{
size_t leftBytes = sourceDataLen - i;
size_t sourceBlockLen = (leftBytes = BLOCK_SIZE) ? leftBytes : BLOCK_SIZE;
size_t encryptedBlockLen = 128;
if(EVP_PKEY_encrypt(ctx, (encryptedData + encryptedDataLen), encryptedBlockLen,
(const unsigned char *)(source.data() + i), sourceBlockLen) = 0)
{
throw std::runtime_error("EVP_PKEY_encrypt failed.");
}
encryptedDataLen += encryptedBlockLen;
}
result = std::string((char*)encryptedData, encryptedDataLen);
}
catch (const std::exception e)
{
LErr(e.what());
}
if (bp != NULL)
{
LInfoCMD(BIO_free(bp));
}
if(rsa != NULL)
{
LInfoCMD(RSA_free(rsa));
}
if (ctx != NULL)
{
LInfoCMD(EVP_PKEY_CTX_free(ctx));
}
if (key != NULL)
{
LInfoCMD(EVP_PKEY_free(key));
}
if (encryptedData != NULL)
{
delete[] encryptedData;
}
return result;
}
======================Java客户端公钥加密=======================
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.security.KeyFactory;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;
import org.apache.commons.codec.binary.Base64;
public class RSAEncrypt {
public static RSAPublicKey loadPublicKeyFromFile(String keyPath)
throws Exception {
BufferedReader br = null;
StringBuilder sb = new StringBuilder();
try {
br = new BufferedReader(new InputStreamReader(new FileInputStream(
keyPath)));
String line = null;
while ((line = br.readLine()) != null) {
if (line.charAt(0) == '-') {
continue;
} else {
sb.append(line);
sb.append('\r');
}
}
} finally {
if (br != null) {
br.close();
}
}
return loadPublicKey(sb.toString());
}
public static RSAPublicKey loadPublicKey(String publicKeyStr)
throws Exception {
Base64 decoder = new Base64();
byte[] buffer = decoder.decode(publicKeyStr);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);
return (RSAPublicKey) keyFactory.generatePublic(keySpec);
}
public static void main(String[] args) throws Exception {
RSAPublicKey publicKey = loadPublicKeyFromFile("public_key.pem");
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] rawText = CommonUtil.readFileContents("from.txt");
FileOutputStream out = null;
try {
out = new FileOutputStream("java_out.bin");
int BLOCK_SIZE = 128 - 11;
for (int i = 0; i rawText.length; i += BLOCK_SIZE) {
int leftBytes = rawText.length - i;
int length = (leftBytes = BLOCK_SIZE) ? leftBytes : BLOCK_SIZE;
out.write(cipher.doFinal(rawText, i, length));
}
} finally {
if (out != null) {
out.close();
}
}
}
}
======================IOS客户端公钥加密=======================
static SecKeyRef _public_key = nil;
- (SecKeyRef) getPublicKey{
if (_public_key == nil){
NSString* filePath = [[NSBundle mainBundle] pathForResource:@"public_key" ofType:@"der"];
NSData* certificateData = [NSData dataWithContentsOfFile:filePath];
SecCertificateRef myCertificate = SecCertificateCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)certificateData);
if (myCertificate == nil) {
LErr(@"无法读取公钥内容");
return nil;
}
SecPolicyRef myPolicy = SecPolicyCreateBasicX509();
SecTrustRef myTrust;
OSStatus status = SecTrustCreateWithCertificates(myCertificate,myPolicy,myTrust);
SecTrustResultType trustResult;
if (status == noErr) {
status = SecTrustEvaluate(myTrust, trustResult);
}else{
return nil;
}
_public_key = SecTrustCopyPublicKey(myTrust);
CFRelease(myCertificate);
CFRelease(myPolicy);
CFRelease(myTrust);
}
return _public_key;
}
- (NSData*) rsaEncrypt:(NSData*) data{
SecKeyRef key = [self getPublicKey];
if (key == nil) {
return nil;
}
size_t cipherBufferSize = SecKeyGetBlockSize(key);
uint8_t* cipherBuffer = malloc(cipherBufferSize * sizeof(uint8_t));
size_t blockSize = cipherBufferSize - 11;
size_t blockCount = (size_t)ceil([data length] / (double)blockSize);
NSMutableData *encryptedData = [[NSMutableData alloc] init];
for (int i=0; i
int bufferSize = (int)MIN(blockSize,[data length] - i * blockSize);
NSData *buffer = [data subdataWithRange:NSMakeRange(i * blockSize, bufferSize)];
OSStatus status = SecKeyEncrypt(key, kSecPaddingPKCS1, (const uint8_t *)[buffer bytes],
[buffer length], cipherBuffer, cipherBufferSize);
if (status == noErr){
NSData *encryptedBytes = [[NSData alloc] initWithBytes:(const void *)cipherBuffer length:cipherBufferSize];
[encryptedData appendData:encryptedBytes];
}else{
if (cipherBuffer) free(cipherBuffer);
return nil;
}
}
JAVA里面RSA加密算法的使用
RSA的Java实现不能一次加密很大的字符,自己处理了一下,见下面的代码。Base64编码类用的是一个Public domain Base64 for java 其他的保存公钥到文件等简单的实现,就不详细说了,看代码吧。==============================================import java.security.*;import java.security.spec.PKCS8EncodedKeySpec;import java.security.spec.X509EncodedKeySpec;import java.util.HashMap;import java.util.Map;import javax.crypto.*;import java.io.*;public class Encryptor {private static final String KEY_FILENAME = "c:\\mykey.dat";private static final String OTHERS_KEY_FILENAME = "c:\\Otherskey.dat";// private static final int KEY_SIZE = 1024;// private static final int BLOCK_SIZE = 117;// private static final int OUTPUT_BLOCK_SIZE = 128;private static final int KEY_SIZE = 2048; //RSA key 是多少位的private static final int BLOCK_SIZE = 245; //一次RSA加密操作所允许的最大长度//这个值与 KEY_SIZE 已经padding方法有关。因为 1024的key的输出是128,2048key输出是256字节//可能11个字节用于保存padding信息了,所以最多可用的就只有245字节了。private static final int OUTPUT_BLOCK_SIZE = 256;private SecureRandom secrand;private Cipher rsaCipher;private KeyPair keys;private MapString, Key allUserKeys;public Encryptor() throws Exception {try {allUserKeys = new HashMapString, Key();secrand = new SecureRandom();//SunJCE Provider 中只支持ECB mode,试了一下只有PKCS1PADDING可以直接还原原始数据,//NOPadding导致解压出来的都是blocksize长度的数据,还要自己处理//参见 另外根据 Open-JDK-6.b17-src( )// 中代码的注释,使用RSA来加密大量数据不是一种标准的用法。所以现有实现一次doFinal调用之进行一个RSA操作,//如果用doFinal来加密超过的一个操作所允许的长度数据将抛出异常。//根据keysize的长度,典型的1024个长度的key和PKCS1PADDING一起使用时//一次doFinal调用只能加密117个byte的数据。(NOPadding 和1024 keysize时128个字节长度)//(2048长度的key和PKCS1PADDING 最多允许245字节一次)//想用来加密大量数据的只能自己用其他办法实现了。可能RSA加密速度比较慢吧,要用AES才行rsaCipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING");} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (NoSuchPaddingException e) {e.printStackTrace();throw e;}ObjectInputStream in;try {in = new ObjectInputStream(new FileInputStream(KEY_FILENAME));} catch (FileNotFoundException e) {if (false == GenerateKeys()){throw e;}LoadKeys();return;}keys = (KeyPair) in.readObject();in.close();LoadKeys();}/** 生成自己的公钥和私钥*/private Boolean GenerateKeys() {try {KeyPairGenerator keygen = KeyPairGenerator.getInstance("RSA");// secrand = new SecureRandom();// sedSeed之后会造成 生成的密钥都是一样的// secrand.setSeed("chatencrptor".getBytes()); // 初始化随机产生器//key长度至少512长度,不过好像说现在用2048才算比较安全的了keygen.initialize(KEY_SIZE, secrand); // 初始化密钥生成器keys = keygen.generateKeyPair(); // 生成密钥组AddKey("me", EncodeKey(keys.getPublic()));} catch (NoSuchAlgorithmException e) {e.printStackTrace();return false;}ObjectOutputStream out;try {out = new ObjectOutputStream(new FileOutputStream(KEY_FILENAME));} catch (IOException e) {e.printStackTrace();return false;}try {out.writeObject(keys);} catch (IOException e) {e.printStackTrace();return false;} finally {try {out.close();} catch (IOException e) {e.printStackTrace();return false;}}return true;}public String EncryptMessage(String toUser, String Message) throws IOException {Key pubkey = allUserKeys.get(toUser);if ( pubkey == null ){throw new IOException("NoKeyForThisUser") ;}try {//PublicKey pubkey = keys.getPublic();rsaCipher.init(Cipher.ENCRYPT_MODE, pubkey, secrand);//System.out.println(rsaCipher.getBlockSize()); 返回0,非block 加密算法来的?//System.out.println(Message.getBytes("utf-8").length);//byte[] encryptedData = rsaCipher.doFinal(Message.getBytes("utf-8"));byte[] data = Message.getBytes("utf-8");int blocks = data.length / BLOCK_SIZE ;int lastBlockSize = data.length % BLOCK_SIZE ;byte [] encryptedData = new byte[ (lastBlockSize == 0 ? blocks : blocks + 1)* OUTPUT_BLOCK_SIZE];for (int i=0; i blocks; i++){//int thisBlockSize = ( i + 1 ) * BLOCK_SIZE data.length ? data.length - i * BLOCK_SIZE : BLOCK_SIZE ;rsaCipher.doFinal(data,i * BLOCK_SIZE, BLOCK_SIZE, encryptedData ,i * OUTPUT_BLOCK_SIZE);}if (lastBlockSize != 0 ){rsaCipher.doFinal(data, blocks * BLOCK_SIZE, lastBlockSize,encryptedData ,blocks * OUTPUT_BLOCK_SIZE);}//System.out.println(encrypted.length); 如果要机密的数据不足128/256字节,加密后补全成为变为256长度的。//数量比较小时,Base64.GZIP产生的长度更长,没什么优势//System.out.println(Base64.encodeBytes(encrypted,Base64.GZIP).length());//System.out.println(Base64.encodeBytes(encrypted).length());//System.out.println (rsaCipher.getOutputSize(30));//这个getOutputSize 只对 输入小于最大的block时才能得到正确的结果。其实就是补全 数据为128/256 字节return Base64.encodeBytes(encryptedData);} catch (InvalidKeyException e) {e.printStackTrace();throw new IOException("InvalidKey") ;}catch (ShortBufferException e) {e.printStackTrace();throw new IOException("ShortBuffer") ;}catch (UnsupportedEncodingException e) {e.printStackTrace();throw new IOException("UnsupportedEncoding") ;} catch (IllegalBlockSizeException e) {e.printStackTrace();throw new IOException("IllegalBlockSize") ;} catch (BadPaddingException e) {e.printStackTrace();throw new IOException("BadPadding") ;}finally {//catch 中 return 或者throw之前都会先调用一下这里}}public String DecryptMessage(String Message) throws IOException {byte[] decoded = Base64.decode(Message);PrivateKey prikey = keys.getPrivate();try {rsaCipher.init(Cipher.DECRYPT_MODE, prikey, secrand);int blocks = decoded.length / OUTPUT_BLOCK_SIZE;ByteArrayOutputStream decodedStream = new ByteArrayOutputStream(decoded.length);for (int i =0 ;i blocks ; i ++ ){decodedStream.write (rsaCipher.doFinal(decoded,i * OUTPUT_BLOCK_SIZE, OUTPUT_BLOCK_SIZE));}return new String(decodedStream.toByteArray(), "UTF-8");} catch (InvalidKeyException e) {e.printStackTrace();throw new IOException("InvalidKey");} catch (UnsupportedEncodingException e) {e.printStackTrace();throw new IOException("UnsupportedEncoding");} catch (IllegalBlockSizeException e) {e.printStackTrace();throw new IOException("IllegalBlockSize");} catch (BadPaddingException e) {e.printStackTrace();throw new IOException("BadPadding");} finally {// catch 中 return 或者throw之前都会先调用一下这里。}}public boolean AddKey(String user, String key) {PublicKey publickey;try {publickey = DecodePublicKey(key);} catch (Exception e) {return false;}allUserKeys.put(user, publickey);SaveKeys();return true;}private boolean LoadKeys() {BufferedReader input;try {input = new BufferedReader(new InputStreamReader(new FileInputStream(OTHERS_KEY_FILENAME)));} catch (FileNotFoundException e1) {// e1.printStackTrace();return false;}
怎样用Java实现RSA加密
提供加密,解密,生成密钥对等方法。�梢愿�模��遣灰��螅�裨蛐�驶岬� keyPairGen.initialize(KEY_SIZE, new SecureRandom()); KeyPair keyPair = keyPairGen.genKeyPair(); return keyPair; } catch (Exception e) { throw new Exception(e.getMessage()); } } /** * 生成公钥 * @param modulus * @param publicExponent * @return RSAPublicKey * @throws Exception */ public static RSAPublicKey generateRSAPublicKey(byte[] modulus, byte[] publicExponent) throws Exception { KeyFactory keyFac = null; try { keyFac = KeyFactory.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider()); } catch (NoSuchAlgorithmException ex) { throw new Exception(ex.getMessage()); } RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(new BigInteger(modulus), new BigInteger(publicExponent)); try { return (RSAPublicKey) keyFac.generatePublic(pubKeySpec); } catch (InvalidKeySpecException ex) { throw new Exception(ex.getMessage()); } } /** * 生成私钥 * @param modulus * @param privateExponent * @return RSAPrivateKey * @throws Exception */ public static RSAPrivateKey generateRSAPrivateKey(byte[] modulus, byte[] privateExponent) throws Exception { KeyFactory keyFac = null; try { keyFac = KeyFactory.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider()); } catch (NoSuchAlgorithmException ex) { throw new Exception(ex.getMessage()); } RSAPrivateKeySpec priKeySpec = new RSAPrivateKeySpec(new BigInteger(modulus), new BigInteger(privateExponent)); try { return (RSAPrivateKey) keyFac.generatePrivate(priKeySpec); } catch (InvalidKeySpecException ex) { throw new Exception(ex.getMessage()); } } /** * 加密 * @param key 加密的密钥 * @param data 待加密的明文数据 * @return 加密后的数据 * @throws Exception */ public static byte[] encrypt(Key key, byte[] data) throws Exception { try { Cipher cipher = Cipher.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider()); cipher.init(Cipher.ENCRYPT_MODE, key); int blockSize = cipher.getBlockSize();//获得加密块大小� i++; } return raw; } catch (Exception e) { throw new Exception(e.getMessage()); } } /** * 解密 * @param key 解密的密钥 * @param raw 已经加密的数据 * @return 解密后的明文 * @throws Exception */ public static byte[] decrypt(Key key, byte[] raw) throws Exception { try { Cipher cipher = Cipher.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider()); cipher.init(cipher.DECRYPT_MODE, key); int blockSize = cipher.getBlockSize(); ByteArrayOutputStream bout = new ByteArrayOutputStream(64); int j = 0; while (raw.length - j * blockSize 0) { bout.write(cipher.doFinal(raw, j * blockSize, blockSize)); j++; } return bout.toByteArray(); } catch (Exception e) { throw new Exception(e.getMessage()); } } /** * * @param args * @throws Exception */ public static void main(String[] args) throws Exception { File file = new File("c:/test.html"); FileInputStream in = new FileInputStream(file); ByteArrayOutputStream bout = new ByteArrayOutputStream(); byte[] tmpbuf = new byte[1024]; int count = 0; while ((count = in.read(tmpbuf)) != -1) { bout.write(tmpbuf, 0, count); tmpbuf = new byte[1024]; } in.close(); byte[] orgData = bout.toByteArray(); KeyPair keyPair = RSA.generateKeyPair(); RSAPublicKey pubKey = (RSAPublicKey) keyPair.getPublic(); RSAPrivateKey priKey = (RSAPrivateKey) keyPair.getPrivate(); byte[] pubModBytes = pubKey.getModulus().toByteArray(); byte[] pubPubExpBytes = pubKey.getPublicExponent().toByteArray(); byte[] priModBytes = priKey.getModulus().toByteArray(); byte[] priPriExpBytes = priKey.getPrivateExponent().toByteArray(); RSAPublicKey recoveryPubKey = RSA.generateRSAPublicKey(pubModBytes,pubPubExpBytes); RSAPrivateKey recoveryPriKey = RSA.generateRSAPrivateKey(priModBytes,priPriExpBytes); byte[] raw = RSA.encrypt(priKey, orgData); file = new File("c:/encrypt_result.dat"); OutputStream out = new FileOutputStream(file); out.write(raw); out.close(); byte[] data = RSA.decrypt(recoveryPubKey, raw); file = new File("c:/decrypt_result.html"); out = new FileOutputStream(file); out.write(data); out.flush(); out.close(); } } (责任编辑:云子)
关于javarsaapi和的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。
发布于:2022-12-01,除非注明,否则均为
原创文章,转载请注明出处。