微信小程式rsa分段加密
阿新 • • 發佈:2019-02-06
前段時間公司要開發app配套的微信小程式,而app的介面是使用rsa加密的。
找了很多資料,發現rsa的祕鑰長度限制了加密時明文的長度。又不能重新寫一套介面。糾結了三天,終於集合各方資料弄出了一個微信小程式試用的rsa分段加密程式.
裡面有好幾種加密
這個是匯出的簽名方法,註釋的兩行是不分段的。不過我測試過,分段的encryptLong也可以相容不分段的encrypt。
function sign(text) {
//var encStr = encrypt_rsa.encrypt(text);//不分段的加密
//encStr = hex2b64(encStr);//不分段加密需要base64一下
var encStr = encrypt_rsa.encryptLong(text);//分段加密
console.log(text)
console.log("加密結果:" + encStr)
return encStr;
}
配套的java端解密的程式碼如下:
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;
import org.apache.commons.codec.binary.Base64;
/**
* RSA演算法
*
*/
public class RSA {
/**
* SIGN_ALGORITHMS
*/
public static final String SIGN_ALGORITHMS = "SHA1WithRSA";
/**
* 公鑰加密
*
* @param content
* @param public_key
* @return
* @throws Exception
*/
public static String signWithPublicKey(String content, String public_key) throws Exception {
byte[] buffer = Base64.decodeBase64(public_key);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);
RSAPublicKey publicKey = (RSAPublicKey) keyFactory.generatePublic(keySpec);
Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());
cipher.init(1, publicKey);
byte[] data = content.getBytes("utf-8");
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
int key_len = publicKey.getModulus().bitLength() / 8 - 11;
for (int i = 0; inputLen - offSet > 0; offSet = i * key_len) {
byte[] cache;
if (inputLen - offSet > key_len) {
cache = cipher.doFinal(data, offSet, key_len);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
++i;
}
byte[] encryptedData = out.toByteArray();
out.close();
return new String(Base64.encodeBase64(encryptedData));
}
public static PrivateKey getPrivateKey(String key) throws Exception {
byte[] keyBytes;
keyBytes = Base64.decodeBase64(key);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
return privateKey;
}
/**
* 私鑰解密
*
* @param content
* @param private_key
* @param input_charset
* @return
* @throws Exception
*/
public static String decryptByPrivateKey(String content, String private_key, String input_charset)
throws Exception {
PrivateKey prikey = getPrivateKey(private_key);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, prikey);
InputStream ins = new ByteArrayInputStream(Base64.decodeBase64(content));
ByteArrayOutputStream writer = new ByteArrayOutputStream();
// rsa解密的位元組大小最多是128,將需要解密的內容,按128位拆開解密
byte[] buf = new byte[128];
int bufl;
while ((bufl = ins.read(buf)) != -1) {
byte[] block = null;
if (buf.length == bufl) {
block = buf;
} else {
block = new byte[bufl];
for (int i = 0; i < bufl; i++) {
block[i] = buf[i];
}
}
writer.write(cipher.doFinal(block));
}
return new String(writer.toByteArray(), input_charset);
}
}