python
版本 3.6
, 在windows以及linux上都进行过测试
由于 python
中 rsa
加密存在长度限制, 虽然可以通过分片加密来解决,
但是更好的做法是通过 rsa
加密传输 aes密钥
给服务器, 携带的信息通过该密钥进行 aes
加密,
服务器通过 rsa私钥
得到 aes密钥
后解析信息, 并继续使用密钥进行双向通信
python中加密使用 pycryptodome
模块
pip install pycryptodome
其中接受的参数text,key均为字符串
from Crypto.PublicKey import RSA from Crypto.Cipher import PKCS1_v1_5 from Crypto.Cipher import AES from base64 import b64decode from base64 import b64encode import re def rsa_encode(text, public_key): key = RSA.importKey(b64decode(public_key)) cipher = PKCS1_v1_5.new(key) return b64encode(cipher.encrypt(text.encode(encoding='utf-8'))).decode('utf-8') def aes_encode(text, key): key = key.encode('utf-8') cipher = AES.new(key, AES.MODE_CBC, key) text = text + (16 - len(text) % 16) * chr(16 - len(text) % 16) return b64encode(cipher.encrypt(text.encode(encoding='utf-8'))).decode('utf-8') def aes_decode(cipher_text, key): key = key.encode('utf-8') cipher = AES.new(key, AES.MODE_CBC, key) text = cipher.decrypt(b64decode(cipher_text)).decode('utf-8') return re.compile('[//x00-//x08//x0b-//x0c//x0e-//x1f/n/r/t]').sub('', text)
java的加密代码不依赖其他包
import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.util.Base64; import java.util.UUID; public class AesUtils { private static final String TYPE = "AES"; private static final String ALGORITHM = "AES/CBC/PKCS5Padding"; private static final String CHARSET = "UTF-8"; public static String createKey(){ return UUID.randomUUID().toString().replace("-","").substring(16); } public static String encrypt(String data, String key) throws Exception { IvParameterSpec ivParameterSpec = new IvParameterSpec(key.getBytes()); SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), TYPE); Cipher cipher = Cipher.getInstance(ALGORITHM); cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivParameterSpec); return Base64.getEncoder().encodeToString(cipher.doFinal(data.getBytes(CHARSET))); } public static String decrypt(String data, String key) throws Exception { IvParameterSpec ivParameterSpec = new IvParameterSpec(key.getBytes()); SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), TYPE); Cipher cipher = Cipher.getInstance(ALGORITHM); cipher.init(Cipher.DECRYPT_MODE, keySpec, ivParameterSpec); return new String(cipher.doFinal(Base64.getDecoder().decode(data.getBytes())), CHARSET); } }
import javax.crypto.Cipher; import java.io.ByteArrayOutputStream; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.Base64; public class RsaUtils { private static final String TYPE = "RSA"; private static final String ALGORITHM = "RSA/ECB/PKCS1PADDING"; private static final String CHARSET = "UTF-8"; private static final int KEY_SIZE = 1024; public static KeyPair createKeyPair() { try { KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(TYPE); keyPairGenerator.initialize(KEY_SIZE); return keyPairGenerator.generateKeyPair(); } catch (Exception e) { return null; } } public static String getPublicKey(KeyPair keyPair) { return Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded()); } public static String getPrivateKey(KeyPair keyPair) { return Base64.getEncoder().encodeToString(keyPair.getPrivate().getEncoded()); } public static String encrypt(String data, String publicKeyString) throws Exception { Cipher cipher = Cipher.getInstance(ALGORITHM); KeyFactory keyFactory = KeyFactory.getInstance(TYPE); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(publicKeyString)); RSAPublicKey publicKey = (RSAPublicKey) keyFactory.generatePublic(keySpec); cipher.init(Cipher.ENCRYPT_MODE, publicKey); return Base64.getEncoder().encodeToString(splitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes(CHARSET))); } public static String decrypt(String data, String privateKeyString) throws Exception { Cipher cipher = Cipher.getInstance(ALGORITHM); KeyFactory keyFactory = KeyFactory.getInstance(TYPE); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKeyString)); RSAPrivateKey privateKey = (RSAPrivateKey) keyFactory.generatePrivate(keySpec); cipher.init(Cipher.DECRYPT_MODE, privateKey); return new String(splitCodec(cipher, Cipher.DECRYPT_MODE, Base64.getDecoder().decode(data)), CHARSET); } private static byte[] splitCodec(Cipher cipher, int mode, byte[] data) throws Exception { int maxBlock = KEY_SIZE / 8 - (mode == Cipher.DECRYPT_MODE ? 0 : 11); try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { byte[] buffer; for (int offset = 0; offset < data.length; offset += maxBlock) { buffer = cipher.doFinal(data, offset, Math.min(maxBlock, data.length - offset)); out.write(buffer, 0, buffer.length); } return out.toByteArray(); } } }