java+JavaScript 实现 非对称加密 rsa

java侧是这样的

package com.tech.sandu.dal.utils;


import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


import javax.crypto.Cipher;


import org.apache.commons.codec.binary.Hex;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


import com.tech.sandu.common.bean.User;
import com.tech.sandu.dal.constant.Constants;


/**
 * 
 */
public class RSAUtil {
public static Logger log = LoggerFactory.getLogger(RSAUtil.class);
private static KeyPair kp = null;
private static Lock lock = new ReentrantLock();
/**
* * 生成密钥对 *

* @return KeyPair *
* @throws EncryptException
*/
private static KeyPair generateKeyPair() throws Exception {
try {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA",
new org.bouncycastle.jce.provider.BouncyCastleProvider());
final int KEY_SIZE = 1024;// 这个值关系到块加密的大小,可以更改,但是不要太大,否则效率会低
keyPairGen.initialize(KEY_SIZE, new SecureRandom());
KeyPair keyPair = keyPairGen.generateKeyPair();
saveKeyPair(keyPair);
return keyPair;
} catch (Exception e) {
throw new Exception(e.getMessage());
}
}


private static KeyPair getKeyPair() {

if(kp!=null)
return kp;

lock.tryLock();
if(kp!=null){
lock.unlock();
return kp;
}

FileInputStream fis = null;
ObjectInputStream oos = null;
try {
fis = new FileInputStream(Constants.RESOURCES_PATH + "RSAKey.txt");
oos = new ObjectInputStream(fis);
kp = (KeyPair) oos.readObject();
} catch (Exception e) {
log.error(e.getMessage(), e);
} finally {
lock.unlock();
try {
if (fis != null)
fis.close();
if (oos != null)
oos.close();
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}

return kp;
}


private static void saveKeyPair(KeyPair kp) throws Exception {
FileOutputStream fos = null;
ObjectOutputStream oos = null;
try {
System.out.println(Constants.RESOURCES_PATH + "RSAKey.txt");
fos = new FileOutputStream(Constants.RESOURCES_PATH + "RSAKey.txt");
oos = new ObjectOutputStream(fos);
oos.writeObject(kp);
} catch (Exception e) {
log.error(e.getMessage(), e);
} finally {
try {
if (fos != null)
fos.close();
if (oos != null)
oos.close();
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
}


/**
* * 生成公钥 *

* @param modulus
*            *
* @param publicExponent
*            *
* @return RSAPublicKey *
* @throws Exception
*/
private 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
*/
private 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 String encrypt(String msg) {
byte[] raw = null;
try {
byte[] data=msg.getBytes(Constants.UTF8);
Cipher cipher = Cipher.getInstance("RSA",
new org.bouncycastle.jce.provider.BouncyCastleProvider());
cipher.init(Cipher.ENCRYPT_MODE,  getKeyPair().getPrivate());
int blockSize = cipher.getBlockSize();// 获得加密块大小,如:加密前数据为128个byte,而key_size=1024
// 加密块大小为127
// byte,加密后为128个byte;因此共有2个加密块,第一个127
// byte第二个为1个byte
int outputSize = cipher.getOutputSize(data.length);// 获得加密块加密后块大小
int leavedSize = data.length % blockSize;
int blocksSize = leavedSize != 0 ? data.length / blockSize + 1
: data.length / blockSize;
raw = new byte[outputSize * blocksSize];
int i = 0;
while (data.length - i * blockSize > 0) {
if (data.length - i * blockSize > blockSize)
cipher.doFinal(data, i * blockSize, blockSize, raw, i
* outputSize);
else
cipher.doFinal(data, i * blockSize, data.length - i
* blockSize, raw, i * outputSize);
i++;
}
} catch (Exception e) {
log.error(e.getMessage(),e);
}
return Hex.encodeHexString(raw);
}
/**
* * 私钥解密 *

* @param key
*            解密的密钥 *
* @param raw
*            已经加密的数据 *
* @return 解密后的明文 *
* @throws Exception
*/
public static String decrypt(String msg)  {
String deCode = null;
try {
byte[] raw = Hex.decodeHex(msg.toCharArray());
Cipher cipher = Cipher.getInstance("RSA",
new org.bouncycastle.jce.provider.BouncyCastleProvider());
cipher.init(cipher.DECRYPT_MODE, getKeyPair().getPrivate());
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++;
}
deCode=new String(bout.toByteArray(),Constants.UTF8);
} catch (Exception e) {
log.error(e.getMessage(),e);
}
return deCode;
}


/**
* * *

* @param args
*            *
* @throws Exception
*/
public static void main(String[] args) throws Exception {
User obj = new User();
obj.setUserName("123123");
obj.setMobile("456546");

String json = GsonTools.toJson(obj);
System.out.println(getKeyPair().getPublic().toString());
System.out.println("***************************");

String miwen = encrypt(json);
System.out.println(miwen);
System.out.println(decrypt(miwen));


}
}


JavaScript 是这样的

var modulus = "82ce8302e55e98a300706326a328ddf5a28e20e39768e59ebb56a7e64c62e76a5ea0a80cb0c908842ccfe9318f346a563f1054546ec3d267de92415ffdcdb6aed4fca3f47c4cb79ff319d750d58c385f199020a3c5b8b660334bd5904b18ee256647d71ccd8cd21dc345090d2a90899268b06e857eeac33d9ec6fbe62c9084c7";
var exponent = "10001";
var key = RSAUtils.getKeyPair(exponent, '', modulus);


function encrypt(a) {
return RSAUtils.encryptedString(key, a);
}
function sendReq(b, c) {
b.reqId  = Date.parse(new Date()) + "_" + Math.ceil(Math.random() * 10000);
var f = encrypt(JSON.stringify(b));
var data={
d:f
};
$.ajax({
url: c,
type: "post",
        dataType: "json", //表示返回值类型,不必须
data:data,
success: function(a) {
console.log(a);
}
});
}

相关文件见附件

猜你喜欢

转载自blog.csdn.net/timy07/article/details/73650704