Android与Windows平台IntelliJ IDEA间RSA加密解密报错问题求助
Android与Windows平台IntelliJ IDEA间RSA加密解密报错问题求助
大家好,我最近遇到了一个跨平台RSA加密的棘手问题,折腾好几天都没搞定,想请各位大佬帮忙分析下:
我的服务端是Windows上的IntelliJ IDEA项目,客户端是Android应用。原本的逻辑很简单:服务端生成RSA密钥对,把公钥发给客户端,客户端用这个公钥加密消息后回传给服务端,但服务端解密的时候直接抛出了错误。
我做了几个测试来排查问题:
- 如果服务端也换成Android平台,整个加密解密流程完全正常,没有任何问题;
- 把两端角色互换(服务端用Android,客户端用IntelliJ),服务端能成功解密,但解密后的消息后面跟着一堆莫名其妙的乱码符号。
下面是相关的核心代码、工具类以及报错的栈追踪信息:
服务端(IntelliJ)代码
ServerSocket serverSocket = new ServerSocket(5556); Socket socket = serverSocket.accept(); System.out.println("Client connected"); DataOutputStream dOut = new DataOutputStream(socket.getOutputStream()); DataInputStream dIn = new DataInputStream(socket.getInputStream()); //Create keys Map<String, Object> RsaKey = rsa.initKey(); String RsaPrivateKey = rsa.getPrivateKey(RsaKey); String RsaPublicKey = rsa.getPublicKey(RsaKey); //send key dOut.writeInt(RsaPublicKey.getBytes().length); dOut.write(RsaPublicKey.getBytes()); Thread.sleep(1000); System.out.println(RsaPublicKey); //read encrypted message int length_pk = dIn.readInt(); byte[] message = new byte[length_pk]; dIn.readFully(message, 0, message.length); String st1 = new String(message); System.out.println(st1 + " " + length_pk + " " + st1.length()); String str = new String(rsa.decryptByPrivateKey(message, RsaPrivateKey)); System.out.println(str);
客户端(Android)代码
Socket client = new Socket("192.168.1.103", 5556); DataOutputStream dOut = new DataOutputStream(client.getOutputStream()); DataInputStream dIn = new DataInputStream(client.getInputStream()); //read key from server int length_pk1 = dIn.readInt(); byte[] publickeyserver1 = new byte[length_pk1]; dIn.readFully(publickeyserver1, 0, publickeyserver1.length); String RsaPublicKeyServer = new String(publickeyserver1); //test key rsa String str = "Who is there?"; byte[] encbyte = rsa.encryptByPublicKey(str.getBytes(), RsaPublicKeyServer); dOut.writeInt(encbyte.length); dOut.write(encbyte);
RSA工具类代码
public static final String KEY_ALGORITHM = "RSA"; public static final String SIGNATURE_ALGORITHM = "MD5withRSA"; private static final String PUBLIC_KEY = "RSAPublicKey"; private static final String PRIVATE_KEY = "RSAPrivateKey"; public static byte[] decryptBASE64(String key) throws Exception { return Base64.getDecoder().decode(key); } public static byte[] decryptByPrivateKey(byte[] data, String key)throws Exception { byte[] keyBytes = decryptBASE64(key); PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, privateKey); return cipher.doFinal(data); } public static byte[] encryptByPublicKey(byte[] data, String key) throws Exception { byte[] keyBytes = decryptBASE64(key); X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicKey = keyFactory.generatePublic(x509KeySpec); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, publicKey); return cipher.doFinal(data); } public static String getPrivateKey(Map<String, Object> keyMap)throws Exception { Key key = (Key) keyMap.get(PRIVATE_KEY); return encryptBASE64(key.getEncoded()); } public static String getPublicKey(Map<String, Object> keyMap)throws Exception { Key key = (Key) keyMap.get(PUBLIC_KEY); return encryptBASE64(key.getEncoded()); } public static Map<String, Object> initKey() throws Exception { KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM); keyPairGen.initialize(1024); KeyPair keyPair = keyPairGen.generateKeyPair(); RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); Map<String, Object> keyMap = new HashMap<String, Object>(2); keyMap.put(PUBLIC_KEY, publicKey); keyMap.put(PRIVATE_KEY, privateKey); return keyMap; }
报错栈追踪
Exception in thread "main" java.lang.RuntimeException: javax.crypto.BadPaddingException: Decryption error at Main.main(Main.java:110) Caused by: javax.crypto.BadPaddingException: Decryption error at java.base/sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:369) at java.base/sun.security.rsa.RSAPadding.unpad(RSAPadding.java:282) at java.base/com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:366) at java.base/com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:400) at java.base/javax.crypto.Cipher.doFinal(Cipher.java:2206) at main.java.rsa.decryptByPrivateKey(rsa.java:134) at Main.main(Main.java:103)
这个RSA工具类我用了很久,同平台下一直没问题,感觉问题应该出在跨平台的传输编码或者JVM差异上,但就是找不到具体原因,麻烦各位帮忙看看!
备注:内容来源于stack exchange,提问作者Роман Дворниченко
相关产品推荐
相关产品推荐

