如何讓 AES 在 Golang 與 Android(Java) 得到一致的加解密結果

因為有某些需要,所以需要和Android client串接API,並且需要使用到AES的加密方式。
在這過程之中,在使用Golang實作AES演算法時碰到了些有趣的問題,在這邊做個記錄,讓剛好有需要的朋友能夠參考。

這篇文章只是筆者碰到的一些問題,也因為筆者對於加解密這塊領域並不是很有研究,相關的知識也是從網路上囫圇吞棗而來的,
所以如果有任何錯誤或是不正確的說明,也請各位朋友們幫我指正,謝謝!

故事背景

由於在Android實作時,是使用內建的AES演算法,在Java相關拿到AES加密器的code是這樣:

Cipher cipher = Cipher.getInstance("AES");

這時候問題就來了,從來沒有了解過加密演算法的筆者,在準備survey Golang相關的AES加解密套件時,
看到了mode, padding等相關的方式。

才發現原來光是"AES"的演算法,就有不同的模式(mode),以及不同的填充(padding)的組合,
Java API doc可以看到他們的蹤跡,下面我們擷取AES的部份列出。

AES/CBC/NoPadding (128)
AES/CBC/PKCS5Padding (128)
AES/ECB/NoPadding (128)
AES/ECB/PKCS5Padding (128)

這時候問題來了,從上面的Java sample code中可以看到Java是直接使用字串"AES"來作為getInstance()的參數,
那我們在使用Golang實作的時候,該使用什麼mode和padding呢?

心得

  • Goalang的byte只能使用正整數,所以在這邊建議Java端如果能夠改動AES key的話,希望能夠使用正整數作為AES Key
//Java AES key
//the AES_KEY cannot be used in Golang
byte [] AES_KEY = {100, 104, 20, 12, -4, 72, -19, 8, 22, 29, 19, -72, 86, 46, 12, 9};
SecretKeySpec skeySpec = new SecretKeySpec(AES_KEY, "AES");

PKCS5 vs. PKCS7?

在AES中,PKCS5和PKCS7兩種模式剛好是一樣的,可以參考相關文章:
1.What is the difference between PKCS#5 padding and PKCS#7 padding
2.对称加密算法的PKCS5和PKCS7填充

究竟Java AES預設使用何種模式?

由於很多人提到預設是 “AES/ECB/PKCS5Padding" AES/ECB/PKCS5Padding AES/ECB/PKCS5Padding when only AES,但是經過好多嘗試以後結果都不對,最後只好自己動手來做實驗。

經過多次實驗後,在Android上跑起getInstance(“AES")預設的模式和填充剛好跟下面的組合吻合
* Mode: CBC
* Padding: PKCS5

Updated 20160709, 感謝 @waywardson 在留言中的補充:
PKCS5填充是PKCS7的子集,即PKCS5只考虑block大小是8个字节的情况,而PKCS7的block大小只要小于255可以是任意值。而AES的block大小固定是16个字节,所以说PKCS5严格说来不能用来给AES做padding。

結論

由於對於加密的不熟悉,造成嘗試了很多不同的方式,一直在嘗試不同的方式,
而對於網路上很多人提到使用getInstance()和"AES"參數和我實驗的不同,
我猜測應該是根據不同的JVM實作的廠商而有不同的方式吧,所以也建議大家在寫code的時候還是盡量寫清楚才好呢!

下面是這次根據網路上個方資料所拼湊出的Golang sample code,各個區段已經忘記是從哪些範例取出了,也歡迎大家補完他。

http://play.golang.org/p/M-ZnBw0aMC

廣告

4 thoughts on “如何讓 AES 在 Golang 與 Android(Java) 得到一致的加解密結果

  1. Yu 說道:

    需要修正一下:PKCS5填充是PKCS7的子集,即PKCS5只考虑block大小是8个字节的情况,而PKCS7的block大小只要小于255可以是任意值。而AES的block大小固定是16个字节,所以说PKCS5严格说来不能用来给AES做padding。

    喜歡

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

您的留言將使用 WordPress.com 帳號。 登出 / 變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 / 變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 / 變更 )

Google+ photo

您的留言將使用 Google+ 帳號。 登出 / 變更 )

連結到 %s