背景:
有一個接口返回的數據是加密的,之前開發那邊提供了一個jar包,人懶,之前的腳本已經用python 寫好了,實在是不想再用java寫一遍,于是乎就一直湊活著用(python里調用java封裝的方法),用了一段時間,好像也挺美。
直到發生了一件事情,當我準備把腳本轉成可視化的工具給同事用的時候,發現,打包的話有點麻煩啊。python在加載jar包的時候,需要加載java虛擬機的動態庫文件。年輕的我以為只要把對應的jvm.dll文件一起打包進去就行了,結果啥用沒有。連本地的文件都跑不起來了,我這才意識到,只要一個動態庫沒用啊,需要的是整個jdk的運行環境,臥槽?這難道是要讓我把整個jdk環境也打包干一套么。聽起來雖然可行,但是一點不靠譜啊。于是乎果斷放棄了。
鑒于不能這么搞了,那就擼起袖子干起來。把jar包反編譯整一套Python的用。
過程
java代碼
public static String decrypt(String data, String key) throws Exception {
byte[] byteKey = key.getBytes();
Key k = toKey(byteKey);
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5PADDING");
cipher.init(2, k);
byte[] byteData = Base64.decodeBase64(data);
return new String(cipher.doFinal(byteData), "UTF-8");
}
反編譯的過程就不說了,不然感覺跑題了啊,反正最后的解密方法就是長這個樣子。
轉換以后
def decrypt_py(data,secretkey):
des_obj = des(secretkey, ECB, secretkey, padmode=PAD_PKCS5)
decodebs64data = base64.b64decode(data)
return des_obj.decrypt(decodebs64data).decode('utf-8')
測試了一下,嗯,沒啥問題,可以用。
坑爹的問題在后邊,開發給了一個DES的key,但是這個key的長度居然是大于8的,這就又在為難我胖虎了。
我還以為DES有啥高端用法,我沒找到,折騰了半天一直都是提示,密鑰必須是8位的錯誤
File "D:\python36\lib\site-packages\pyDes.py", line 400, in __init__
raise ValueError("Invalid DES key size. Key must be exactly 8 bytes long.")
ValueError: Invalid DES key size. Key must be exactly 8 bytes long.
于是我就又去認認真真地看了一遍java那邊的解密方法,這就是坑爹的地方了
請看DESKeySpec的構造函數
public DESKeySpec(byte[] var1, int var2) throws InvalidKeyException {
if(var1.length - var2 < 8) {
throw new InvalidKeyException("Wrong key size");
} else {
this.key = new byte[8];
System.arraycopy(var1, var2, this.key, 0, 8);
}
}
原來是傳入的字符串做了截取,不管傳了多長的字符串,都只取前邊的8位拷貝出來。回手掏,掉頭就把python里邊后邊多余的字符刪掉了,運行完美!
嗯…記錄下,主要是想說,還是要認真有耐心一點,有問題要看看代碼,不能迎頭就是各種百度,結果啥用都沒有。