1、公钥私钥生成工具
参考: http://web.chacuo.net/netrsakeypair
2、python实现
import base64
from Crypto.PublicKey import RSA
pub_key = '''-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4kIvaLa1g+cf0UYN3gH5
Eypbu7jwgrWT1QWDx4OKMCokzwK3dvFF+JalTZ7stGBEgvn88gdKZMzluBtXy/Cp
QUWBYkL4i19BjJ7cpCOtvlIpVS9H3uaqaA3WDT4q/SpTRP2ToWWz2mJ7Jm8TueB0
XljBGnVLPZ3RuGjOx+fagzq6qb0dOVri/BcodrOUFQ40f+gx+AIIEo02VPccIT/l
NCZFzfftvuMbkOiruSR5RxPe48UQzoBuHb/4xisUFxkF7k8ncLCPk4jmr/MAQzaC
AfCwNLA5/mVYE0oulGos7C+bDelGAUPk9iJeSGa4bpkLll/2UUcdeP4pYwj1ytnb
vwIDAQAB
-----END PUBLIC KEY-----
'''
pri_key = '''-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDiQi9otrWD5x/R
Rg3eAfkTKlu7uPCCtZPVBYPHg4owKiTPArd28UX4lqVNnuy0YESC+fzyB0pkzOW4
G1fL8KlBRYFiQviLX0GMntykI62+UilVL0fe5qpoDdYNPir9KlNE/ZOhZbPaYnsm
bxO54HReWMEadUs9ndG4aM7H59qDOrqpvR05WuL8Fyh2s5QVDjR/6DH4AggSjTZU
9xwhP+U0JkXN9+2+4xuQ6Ku5JHlHE97jxRDOgG4dv/jGKxQXGQXuTydwsI+TiOav
8wBDNoIB8LA0sDn+ZVgTSi6UaizsL5sN6UYBQ+T2Il5IZrhumQuWX/ZRRx14/ilj
CPXK2du/AgMBAAECggEABSeG1vbamb+pLOZQqI8Y8oPThSpIaGHklUTD5MatXj2H
iyO/tDj45BnieCs3r0BGL0mspoLeAf/c992/mUjJQlBoCyoFaX9pCeAQnLinW5+Z
i3RBSeWtWiN+jdyttAjDzt2MAHBFsaLutUhwhZqEbCXPeF/Vr/ipb28LzugMRVMF
M5zuUkbUgqmRm7nHbdR2H5ghkMfh01UGflhLxqZUv2+ILuPqs66Zbw5dX296l5bP
d4JCx95BiHMT+XfLapSEVuxXZDdZ/YOH4ceZ22zxOYygXEq2c13sHtQq/h98O82i
0JaTEsDWde9Pc2TJ8m0c1I1fdpXEPie5U9i3ckpK2QKBgQD/KLi5sMGccg84S9Vu
WZR4qsgnQ0xOaBMQDGtASUxSi2CNE74yXQki1eOk1acx3i5Ff3bq1g6cSIAeNr8/
ayYYut6lrGoSJwqiAU+6DQVMs4yH9zPgPQg5ldDQitO6QDcl3KLRQjiwYQmZQaNt
XkV/Czrb6aEHTUJuJ6l3teoDmwKBgQDjARSEl1Gjj60Dqgedp5qp0ab1dYiGiDWX
ux9MrZSu/cWdkDLxdowbFT7ovqZBOaypoF2H2x4TNl3JqbH7BBgmDW21oCPRdzTQ
CA+IOMxyF7gFGn5zzf0DnM2WklYWM5+IL9Y0DAwykFW+54PKxQrNlkFkfFtbSQ9T
DcFZjuUErQKBgQD6/UGIVxh8Ha5fACl4HOHxOH0eMhLTZYiq1qyBVhifcb6Nx4fl
3qJoA+GjeQ63/QejEVkWc213ydFM5ymE5o9Y8Cim60yDgqfw6D1WlAxMgKmR7Va4
ExEOJBJ9sLHImfYlZj06fltpFGruuCRcJslRyOgi/lOJ7TOVS6pluSnyVQKBgQCr
egtnxW60ITpOxEgQfaVFlsuKLAi/p3Dkd0PDhnQEZEq9JUp2QFjBtKDa6/lm2Axn
7m34zDrBxJXAWmHJ/mPHiulPA/NKrcPFSfGBs3Ys0WH+6O6QyA/ShMaAcXZ6OvDN
zWT/2AH2yDUdioFx0LrCZjhrkczo/h2HXaKq5lh12QKBgQDY5cdQsR0KvjpB/w9t
+Kk3uSXw10LkCCCKgjw6FopWOzux9HqNyXYMY9eHFWnKrxpwJ/yqPHy62hjBnpRT
mq0aVnWisWTWELRWcPckuehx150jzQ+Ur00Rt96ArV/pP+iCrKN6vDrfbZa3Lkg4
Gd8zP2aROXWnVgIYowOvIat1PQ==
-----END PRIVATE KEY-----
'''
def b64_encrypt(func):
def _wrapper(*args, **kwargs):
str_result = func(*args, **kwargs)
return base64.b64encode(str_result)
return _wrapper
def b64_decrypt(func):
def _wrapper(str_data):
return func(base64.b64decode(str_data))
return _wrapper
@b64_encrypt
def encrypt(data):
pk = RSA.importKey(pub_key)
en, size = "", 256
for i in range(0, len(data), size): # 长文本分段加密
tmp_data = data[i: i + size]
en += pk.encrypt(tmp_data, 0)[0]
return en
@b64_decrypt
def decrypt(data):
sk = RSA.importKey(pri_key)
out_text, size = "", 256
for i in range(0, len(data), size):
tmp_text = data[i:i + size]
out_text += sk.decrypt(tmp_text)
return out_text
def test(data):
en_text = encrypt(data)
de_text = decrypt(en_text)
print '--' * 30
print 'data =\t', data
print 'encrypt =\t', en_text
print de_text == data
print
if __name__ == '__main__':
test("hello")
test("abcdefg" * 50)
3、Java实现
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.Cipher;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.StringReader;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
public class RSAUtils {
private static final String PUB_KEY = "-----BEGIN PUBLIC KEY-----\r" +
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsgDqCUjJ2lAksfIq2406\r" +
"C7FRTvBZLLs5RvsQq64uVc4JPKmbpa+tjknfHkFHrBZ+GcprytAAgCkElNTsNFms\r" +
"hy8OBSm5Vu925vvkjg38A8R87PVSOwPv8SktzBpzT+iPgLPFCp6JYm7jlYXqNqgG\r" +
"f8j2EHaiwQ1O+eYHB3dR77vBEVZqx4Sbo0TGk/QV+u1f01vA7M8Lit2qqKoghJl0\r" +
"ROexmTgyuSmSW3UEfDOr3iZwaBP1Lq4DGXdiJGTpONDeeCYOY/GWHjaqELyL8Tz4\r" +
"GOIuO0SjiQ60BTT5IVKa3IzW4bsIiBW7LR2PKKulU9HQmAZGbEV98F5mxAypK7W+\r" +
"XwIDAQAB\r" +
"-----END PUBLIC KEY-----\r";
private static final String PRI_KEY = "-----BEGIN PRIVATE KEY-----\r" +
"MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCyAOoJSMnaUCSx\r" +
"8irbjToLsVFO8FksuzlG+xCrri5Vzgk8qZulr62OSd8eQUesFn4ZymvK0ACAKQSU\r" +
"1Ow0WayHLw4FKblW73bm++SODfwDxHzs9VI7A+/xKS3MGnNP6I+As8UKnolibuOV\r" +
"heo2qAZ/yPYQdqLBDU755gcHd1Hvu8ERVmrHhJujRMaT9BX67V/TW8DszwuK3aqo\r" +
"qiCEmXRE57GZODK5KZJbdQR8M6veJnBoE/UurgMZd2IkZOk40N54Jg5j8ZYeNqoQ\r" +
"vIvxPPgY4i47RKOJDrQFNPkhUprcjNbhuwiIFbstHY8oq6VT0dCYBkZsRX3wXmbE\r" +
"DKkrtb5fAgMBAAECggEAKT8Q/AnDzDSZ7CnjSHCXLLJv1szWvQi9Ivd2S3HXBsbx\r" +
"WP8sM95bZwczDj2uL/AeVDeVdq9wDkJy71HPUeodkk2TABtE+SIP+UIRGeGfrffP\r" +
"wtCtt0MYTFdwZ0URx0hqSDZfyDAoQYjUb4dSWEvjBaU5b2MuH3HIBRwKMO6zK8uA\r" +
"y9dUFGSC4ZhHi2UT8pMlhqX9Z+blZYtqzvNP/DzLQWXG8BmiA3vf0y9uPxEauUJH\r" +
"Zu1kdze0e8N7H4QdjN9rwqUP8LuC6F8y2TqGec0xQTpZ/t8LM4iJY1kjhu5Su7sK\r" +
"DetShx4sdpOOHlPuGgOQ3zJKmkFm8EDUvOaVfj7YAQKBgQDgApWKYyRsaWD7rE2V\r" +
"amITJjDQYHHb6gvSN8kZmaVbknl0/Y2S6Uqj9L1iLnYx4NGEWNbI9KrsRPiONBdd\r" +
"bmrCFBefDxnueZtNkFzBoFm2zAbDqQZ5OM1mgw5kwKLBUk2hEsnvJPNnHZ3/vrg8\r" +
"lbyHXeJwsYLdxDvew8V1XNLaAQKBgQDLbGmOKk7d+HZvTlYreSCWyTocUAIzS7Vq\r" +
"5NLicgmU5pq8OPBHMIArVy/n6tSb1WVdMAfPzYNyvzAfG17Br0aCT5xvCAxbnfaT\r" +
"AwgI0Yz+Xktl1JxUrxEbrd7aPAp7Z/Za6aegRku0PM+wjtWhnwDW9Aa983gg5zDp\r" +
"NOtJtYbYXwKBgBE/YbA0Dfvi6Tq3e4nDlSWQTTXeFyYtkRdwgCVedSLl1kAxvZLQ\r" +
"L5UMJQDIPwV8H+WmyXLTk815SgH49MuW0tV6oo72pLJ93n1MXjfyVrYCY4rxGrR+\r" +
"sSHxeUw8oMttwNhkD/Q/zhXka+PjFWBkzw1FJ0gyArd8gneWbz+oE/wBAoGBAKoI\r" +
"yIJootuvX2/STvyvlqnzMXuQ9QXjdpUPB6b4I0IvL4+9GDqpM7kGe6ijBWvsh3nJ\r" +
"N/5ejk1Pue2Gd0H2PD2YRe4ZEBtUglKH6iNU5UGJmARaHwI6A1bbkrdgEHLuh2Ge\r" +
"hNrXZ1gUrJWsDq21toH2H9yOsg7usFd+QF2wOjKJAoGBAIBmtDdMnofU00Om6pg5\r" +
"s+G2fp91/vCVUCcqUvwxcmw7dlDaDY85WN+XjgYReKNqhNbDPoZP26oJP+tzoSPO\r" +
"kkaLfV86dauKJqRsVJ0a1mpRYYNzfKT/v3uhCLc+mrnhUTg+/Iq5QR9fRmN09252\r" +
"UmqtRtkQVtfIWSC9S4wCrGjV\r" +
"-----END PRIVATE KEY-----\r";
private static final int sliceSize = 256;
private PublicKey publicKey;
private PrivateKey privateKey;
public RSAUtils() throws Exception {
this(PUB_KEY, PRI_KEY);
}
public RSAUtils(String publicKey, String privateKey) throws Exception {
this.publicKey = this.loadPublicKey(publicKey);
this.privateKey = this.loadPrivateKey(privateKey);
}
private String prepareKeyString(String raw) throws Exception {
StringBuilder sb = new StringBuilder();
BufferedReader br = new BufferedReader(new StringReader(raw));
String line;
while ((line = br.readLine()) != null) {
if (line.startsWith("-")) {
continue;
}
sb.append(line.trim()).append("\r");
}
br.close();
return sb.toString();
}
private PublicKey loadPublicKey(String strPk) throws Exception {
return KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(
Base64.decodeBase64(this.prepareKeyString(strPk).getBytes())
));
}
private PrivateKey loadPrivateKey(String strPk) throws Exception {
return KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(
Base64.decodeBase64(this.prepareKeyString(strPk).getBytes())
));
}
public String encrypt(String text) throws Exception {
Cipher cipher = Cipher.getInstance("RSA", new BouncyCastleProvider());
cipher.init(Cipher.ENCRYPT_MODE, this.publicKey);
byte[] srcBytes = text.getBytes();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
for (int i = 0; i < srcBytes.length; i += sliceSize) {
int inputLen = (i + sliceSize >= srcBytes.length) ? srcBytes.length - i : sliceSize;
byte[] buf = cipher.doFinal(srcBytes, i, inputLen);
bos.write(buf);
}
return Base64.encodeBase64String(bos.toByteArray());
}
public String decrypt(String text) throws Exception {
byte[] srcBytes = Base64.decodeBase64(text);
Cipher cipher = Cipher.getInstance("RSA", new BouncyCastleProvider());
cipher.init(Cipher.DECRYPT_MODE, this.privateKey);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
for (int i = 0; i < srcBytes.length; i += sliceSize) {
byte[] buf = cipher.doFinal(srcBytes, i, sliceSize);
bos.write(buf);
}
return new String(bos.toByteArray());
}
public static void main(String[] args) throws Exception {
RSAUtils m = new RSAUtils();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1; i++) {
sb.append("hello");
}
String result = m.encrypt(sb.toString());
String expectEncryptStr = "rfW4LBNU6EDAJ135Uiqk8kvWgf0x9m4NZCn1L5/6bgWAKA8OlIp7rT/uyueRrirCmZ1cXAQcNAQmRKhMI7y4or2YqrxT/TqV+dQIyyAea0Yq6HIfU9IrpvDmgcPNh91WdtLo6CYFqvg2VSBELdUUL2x/Z7B4oQ/rxTM5XX1AogiFa6EM5PtYE9YTMBsQzy3RoAGA1o7NqrziJTtJT5Os0UFAWikFmgZbLzAVsXrg//NLW0BYCoXEVrMP9V+/OGd3PocH3apCvAgpajEKtzSSIj6oAd+meM9wdQFZ43+gY8j9MVYSidYyygQhN7GUTB3ms878zmP3YKIHMKDBArdKsw==";
System.out.println(result);
System.out.println(result.equals(expectEncryptStr));
System.out.println(m.decrypt(result));
}
}
Gradle依赖:
// https://mvnrepository.com/artifact/com.squareup.jnagmp/bouncycastle-rsa compile group: 'com.squareup.jnagmp', name: 'bouncycastle-rsa', version: '2.1.0' // https://mvnrepository.com/artifact/commons-codec/commons-codec compile group: 'commons-codec', name: 'commons-codec', version: '1.11'