python
版本3.6
, 在windows以及linux上都进行过测试
由于python
中rsa
加密存在长度限制, 虽然可以通过分片加密来解决, 但是更好的做法是通过rsa
加密传输aes密钥
给服务器, 携带的信息通过该密钥进行aes
加密, 服务器通过rsa私钥
得到aes密钥
后解析信息, 并继续使用密钥进行双向通信
python中加密使用pycryptodome
模块
1 pip install pycryptodome
Python 其中接受的参数text,key均为字符串
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 from Crypto.PublicKey import RSAfrom Crypto.Cipher import PKCS1_v1_5from Crypto.Cipher import AESfrom base64 import b64decodefrom base64 import b64encodeimport redef 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 java的加密代码不依赖其他包
AesUtils 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 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); } }
RsaUtils 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 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(); } } }