lua-lockbox padding problem

前言

在最近的項(xiàng)目中玛追,使用nginx+lua來(lái)進(jìn)行安全管理,其中要用到des算法扎即;根據(jù)luajit官方的推薦,采用是lua-resty-nettle,但在使用過(guò)程中發(fā)現(xiàn)花沉,lua-resty-nettle采用的是0補(bǔ)位,而JDK中實(shí)現(xiàn)的是PKCS5Padding进鸠;

繼續(xù)尋找新的類庫(kù)稠曼,由于團(tuán)隊(duì)對(duì)c并不熟悉,考慮到后續(xù)的維護(hù)方便客年,優(yōu)先選擇純lua的實(shí)現(xiàn)霞幅,這時(shí)lua-lockbox進(jìn)入到我們的視野;但在使用過(guò)程中發(fā)現(xiàn)雖然java和lua代碼采用相同的分塊模式(ECB),相同的補(bǔ)位(java是PKCS5Padding,lua是PKCS7Padding)量瓜,但lua加密的數(shù)據(jù)無(wú)法用java解密司恳。報(bào)錯(cuò)信息為:

javax.crypto.BadPaddingException: Given final block not properly padded;

錯(cuò)誤信息很明細(xì)绍傲,lua補(bǔ)位不正確扔傅;直接看源碼pkcs7.lua,發(fā)現(xiàn)其補(bǔ)位邏輯如下:


local Stream = require("lockbox.util.stream");

local PKCS7Padding = function(blockSize,byteCount)

local paddingCount = blockSize - ((byteCount -1) % blockSize) + 1;

local bytesLeft = paddingCount;

local stream = function()

if bytesLeft > 0 then

bytesLeft = bytesLeft - 1;

return paddingCount;

else

return nil;

end

end

return stream;

end

return PKCS7Padding;

那么PKCS5Padding到底是如何補(bǔ)位的呢烫饼?具體可參考如下資料:

  • PKCS #7: Cryptographic Message Syntax Standard
    :An RSA Laboratories Technical Note, Version 1.5. Revised November 1, 1993.

  • PKCS #5: Password-Based Encryption Standard:
    An RSA Laboratories Technical Note, Version 1.5. Revised November 1, 1993. f

    閱讀上面的資料猎塞,可以發(fā)現(xiàn)PKCS #7 填充字符串由一個(gè)字節(jié)序列組成,每個(gè)字節(jié)填充該字節(jié)序列的長(zhǎng)度杠纵。 假定塊長(zhǎng)度為 8荠耽,數(shù)據(jù)長(zhǎng)度為 9,則填充用八位字節(jié)數(shù)等于 7比藻,數(shù)據(jù)等于 FF FF FF FF FF FF FF FF FF:
    數(shù)據(jù): FF FF FF FF FF FF FF FF FF
    PKCS7 填充: FF FF FF FF FF FF FF FF FF 07 07 07 07 07 07 07

    而根據(jù)lua-lockbox的補(bǔ)位邏輯铝量,補(bǔ)位結(jié)果為:
    lua-lockbox補(bǔ)位:FF FF FF FF FF FF FF FF FF 09 09 09 09 09 09 09 09 09
    因此lua-lockbox對(duì)于PKCS7Padding的實(shí)現(xiàn)有誤,修改代碼為:

local paddingCount = blockSize - (byteCount % blockSize);

加密的補(bǔ)位問(wèn)題解決了银亲,但又發(fā)現(xiàn)另外一個(gè)問(wèn)題慢叨,解密時(shí),lua-lockbox沒(méi)有去掉補(bǔ)位數(shù)據(jù)群凶,從上面的pkcs7.lua代碼可以看到插爹,lua-lockbox并沒(méi)有實(shí)現(xiàn)該邏輯哄辣,采用臨時(shí)解決方案请梢,修改ecb.lua或cbc.lua,將其解密的finish方法修改為:

        local data=Stream.toArray(outputQueue.pop)
        local paddingByte=data[#data]

        local realLength=#data-paddingByte--如果有padding,計(jì)算去除padding后的長(zhǎng)度
        local padded=true
        for i=#data,realLength+1,-1 do
            if(data[i]~=paddingByte) then
                padded=false
            end
        end
        print("realLength is "..realLength)
        local paddedBytes=Array.slice(data,1,realLength)
        
        if padded then
            Array.writeToQueue(outputQueue,paddedBytes)
        end
        --paddingStream = padding(blockCipher.blockSize,inputQueue.getHead());
        --public.update(paddingStream);

        return public;

目前的解決辦法比較粗糙赠尾,后續(xù)有時(shí)間進(jìn)行完善;

PKCS#5/7區(qū)別

在PKCS5Padding中毅弧,明確定義Block的大小是8位气嫁,而PKCS7Padding定義中,塊的大小是不確定的够坐,可以在1-255之間(塊長(zhǎng)度超出255的尚待研究)寸宵,填充值的算法都是一樣的:

value=k - (l mod k)  ,K=塊大小,l=數(shù)據(jù)長(zhǎng)度元咙,如果l=8, 則需要填充額外的8個(gè)byte的8

DES填充方式

DES是對(duì)64位數(shù)據(jù)的加密算法梯影,如數(shù)據(jù)位數(shù)不足64位的倍數(shù),需要填充庶香,補(bǔ)充到64位的倍數(shù)甲棍。

  • NoPadding
    API或算法本身不對(duì)數(shù)據(jù)進(jìn)行處理,加密數(shù)據(jù)由加密雙方約定填補(bǔ)算法赶掖。例如若對(duì)字符串?dāng)?shù)據(jù)進(jìn)行加解密感猛,可以補(bǔ)充\0或者空格,然后trim

  • PKCS5Padding
    加密前:數(shù)據(jù)字節(jié)長(zhǎng)度對(duì)8取余奢赂,余數(shù)為m陪白,若m>0,則補(bǔ)足8-m個(gè)字節(jié),字節(jié)數(shù)值為8-m膳灶,即差幾個(gè)字節(jié)就補(bǔ)幾個(gè)字節(jié)咱士,字節(jié)數(shù)值即為補(bǔ)充的字節(jié)數(shù),若為0則補(bǔ)充8個(gè)字節(jié)的8
    解密后:取最后一個(gè)字節(jié)轧钓,值為m司致,則從數(shù)據(jù)尾部刪除m個(gè)字節(jié),剩余數(shù)據(jù)即為加密前的原文

  • SSL3Padding
    SSL3.0協(xié)議定義的填補(bǔ)算法

參考資料

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末聋迎,一起剝皮案震驚了整個(gè)濱河市脂矫,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌霉晕,老刑警劉巖庭再,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件牺堰,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡恨搓,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)斧抱,“玉大人常拓,你說(shuō)我怎么就攤上這事辉浦。” “怎么了宪郊?”我有些...
    開(kāi)封第一講書人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵掂恕,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我弛槐,道長(zhǎng)懊亡,這世上最難降的妖魔是什么乎串? 我笑而不...
    開(kāi)封第一講書人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮灌闺,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘甩卓。我一直安慰自己,他們只是感情好逾柿,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布宅此。 她就那樣靜靜地躺著,像睡著了一般父腕。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上萧诫,一...
    開(kāi)封第一講書人閱讀 51,554評(píng)論 1 305
  • 那天枝嘶,我揣著相機(jī)與錄音,去河邊找鬼群扶。 笑死镀裤,一個(gè)胖子當(dāng)著我的面吹牛缴饭,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播茴扁,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼汪疮,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了智嚷?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤稍浆,失蹤者是張志新(化名)和其女友劉穎猜嘱,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體朗伶,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡论皆,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了点晴。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡陪竿,死狀恐怖屠橄,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情仇矾,我是刑警寧澤,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布姐仅,位于F島的核電站,受9級(jí)特大地震影響掏膏,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜馒疹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一颖变、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧腥刹,春花似錦、人聲如沸衔峰。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)穴肘。三九已至,卻和暖如春梢褐,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背盈咳。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留鸣剪,地道東北人丈积。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像江滨,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子告唆,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容