iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 22
1
Security

看完眼眶濕濕的App開發者慘烈對抗險惡資安環境血與淚的控訴!系列 第 22

Day 22. 加密演算法要注意的那些毛 (二) - 填充模式

這個章節來講講另外一種 ,關於填充模式(Padding)

081HK0903_BF9Z2.jpg.thumb.500.500

圖片來源 Mr Doodle

填充模式(Padding)

前面加密章節有提到,加密是透過 區塊(block) 進行加密,會將明文排列成特定的形狀(如:正方形、長方形等),但並不是每次都可以切割初剛好的區塊,明文不能完全符合形狀,就需要添加字母來填滿形狀,而如果用無意義的字母來填充則更可以阻礙一些密碼分析

我們常用的填充的方式就包括ZeroPadding、PKCS5Padding與PKCS7Padding,就來介紹有哪些填充方式

NoPadding

不填充,如果加密內容不是8字節整數倍加密則會報錯

ZeroBytePadding

所有需要填充的地方都以0填充。

範例如下:Block 大小為 8 Byte,需要填充 4 Byte(以十六進位表示)

| DD DD DD DD DD DD DD DD | DD DD DD DD 00 00 00 00 |

PKCS#7 Padding

每個填充字節的值是用於填充的字節數,即是說,若需要填充 N 個字節,則每個填充字節值都是 N 。 填充的字節數取決於算法可以處理的最小數據塊的字節數量

01
02 02
03 03 03
04 04 04 04
05 05 05 05 05
etc.

範例如下:Block 大小為 8 Byte,需要填充 4 Byte(以十六進位表示)

| DD DD DD DD DD DD DD DD | DD DD DD DD 04 04 04 04 |

PKCS#5 Padding

​ PKCS#5 和PKCS#7運算方式都相同 的唯一區別是PKCS5 只能用來填充 8 Byte (64bit)的Block,除此之外可以混用。

範例如下:Block 大小為 8 Byte,需要填充 4 Byte(以十六進位表示)

| DD DD DD DD DD DD DD DD | DD DD DD DD 04 04 04 04 |

PKCS#5 PKCS#7 到底哪裡不同 要怎麼選??

最大的差異式兩個針對BlickSize 不同

PKCS#5只對於8 Byte(BlockSize=8)進行填充,填充內容為 0x01- 0x08;

但是PKCS#7不僅僅是對 8 Byte填充,其BlockSize範圍是 1-255 Byte。

所以,PKCS#5可以向上轉換為PKCS#7,但是PKCS#7不一定可以轉換到PKCS#5

用PKCS#7填充加密的密文,用PKCS#5解出來是錯誤的

因此很多人說 PKCS#5 = PKCS#7 論調就是錯的,只有運算方式相同,但使用限制就大大的不同

因此,從本質上講,PKCS#5 Padding 是 PKCS#7 子集

嚴格來說,PKCS#5 Padding 不能用於AES 因為 AES 最小的128bit 是 16 Byte。

只有在使用 RC2 / RC5和 DES/3DES 演算法的情況,這些算法 BlockSize=64bits=8bytes 這時考慮使用 PKCS#5 Padding

在 AES 上使用 PKCS#5 ,會硬生將AES 16 Byte 改採用 8 Byte 方式填充,雖然可以運作
但還是極力不建議在 AES上使用 PKCS#5 ,而是使用 PKCS#7

請注意,PKCS#5和PKCS#7都不是用來描述填充機制的標準。填充部分只是所定義功能的一小部分。

PKCS#5 是基於密碼加密標準(Password-based Encryption Standard)RFC 2898

PKCS#7 密碼訊息語法標準(Cryptographic Message Syntax Standard)RFC 2315

詳細可見 PKCS (Public Key Cryptography Standards)

其他填充模式

當然還有其他填充模式,有興趣的讀者可以在深入研究

  • ANSI X9.23
  • ISO 10126

  • ISO 97971

小結

填充模式,真的是很容易讓人搞的暈頭轉向的議題,如果 Padding 設定錯誤,是無法解密最容易遇到是跨平台溝通

所以都要確保雙方使用的 Padding 模式都是相同的

像是 JAVA 預設就只有 PKCS#5 , 沒有 PKCS#7,需要另外實作

在 PKCS#5 PKCS#7 真的是眾說紛紜,我也從使用至今看了很多資料,爬過很多文

才有點小小心得,也不敢說絕對正確

以下是我的建議

在 DES/3DES/RC2/RC4使用 PKCS#5 (不過這些演算法嚴格來說都被棄用了)

AES 使用 PKCS#7

下下策就是使用 ZeroBytePadding

參考資料

https://en.wikipedia.org/wiki/PKCS

https://zh.wikipedia.org/wiki/%E5%85%AC%E9%92%A5%E5%AF%86%E7%A0%81%E5%AD%A6%E6%A0%87%E5%87%86

https://en.wikipedia.org/wiki/Padding_(cryptography)

https://crypto.stackexchange.com/questions/9043/what-is-the-difference-between-pkcs5-padding-and-pkcs7-padding


上一篇
Day 21. 加密演算法要注意的那些毛 (一) - 加密模式
下一篇
Day 23. 非對稱式加密演算法 - RSA (觀念篇)
系列文
看完眼眶濕濕的App開發者慘烈對抗險惡資安環境血與淚的控訴!31

1 則留言

0
Negroni
iT邦新手 5 級 ‧ 2021-04-13 11:00:20

RFC2898[https://tools.ietf.org/html/rfc2898]

...... with a 128-bit block size, the padding string consists of 16-(||M|| mod 16) octets each with value 16-(||M|| mod 16).

根據文件說法,PKCS5是有支援到128-bit(16 bytes)的,所以Android AES才能使用PKCS5,且這樣如果block size <= 16 bytes的話就像相容於PKCS7了

我要留言

立即登入留言