lua-lockbox padding problem

在最近的项目中,使用nginx+lua来进行安全管理,其中要用到des算法;根据luajit官方的推荐,采用是lua-resty-nettle,但在使用过程中发现,lua-resty-nettle采用的是0补位,而JDK中实现的是PKCS5Padding;

继续寻找新的类库,由于团队对c并不熟悉,考虑到后续的维护方便,优先选择纯lua的实现,这时lua-lockbox进入到我们的视野;但在使用过程中发现虽然java和lua代码采用相同的分块模式(ECB),相同的补位(java是PKCS5Padding,lua是PKCS7Padding),但lua加密的数据无法用java解密。报错信息为:

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

错误信息很明细,lua补位不正确;直接看源码pkcs7.lua,发现其补位逻辑如下: 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到底是如何补位的呢?具体可参考如下资料:

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

阅读上面的资料,可以发现PKCS #7 填充字符串由一个字节序列组成,每个字节填充该字节序列的长度。 假定块长度为 8,数据长度为 9,则填充用八位字节数等于 7,数据等于 FF FF FF FF FF FF FF FF FF: 数据: 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

而根据lua-lockbox的补位逻辑,补位结果为: lua-lockbox补位:FF FF FF FF FF FF FF FF FF 09 09 09 09 09 09 09 09 09 因此lua-lockbox对于PKCS7Padding的实现有误,修改代码为: local paddingCount = blockSize - byteCount% blockSize; 加密的补位问题解决了,但又发现另外一个问题,解密时,lua-lockbox没有去掉补位数据,从上面的pkcs7.lua代码可以看到,lua-lockbox并没有实现该逻辑,采用临时解决方案,修改ecb.lua或cbc.lua,将其解密的finish方法修改为: local data=Stream.toArray(outputQueue.pop) local paddingByte=data[#data]

  local realLength=#data-paddingByte--如果有padding,计算去除padding后的长度
  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;

目前的解决办法比较粗糙,后续有时间进行完善;

PKCS#5/7区别

在PKCS5Padding中,明确定义Block的大小是8位,而PKCS7Padding定义中,块的大小是不确定的,可以在1-255之间(块长度超出255的尚待研究),填充值的算法都是一样的: value=k - (l mod k) ,K=块大小,l=数据长度,如果l=8, 则需要填充额外的8个byte的8 DES填充方式

DES是对64位数据的加密算法,如数据位数不足64位的倍数,需要填充,补充到64位的倍数。

NoPadding API或算法本身不对数据进行处理,加密数据由加密双方约定填补算法。例如若对字符串数据进行加解密,可以补充\0或者空格,然后trim

PKCS5Padding 加密前:数据字节长度对8取余,余数为m,若m>0,则补足8-m个字节,字节数值为8-m,即差几个字节就补几个字节,字节数值即为补充的字节数,若为0则补充8个字节的8 解密后:取最后一个字节,值为m,则从数据尾部删除m个字节,剩余数据即为加密前的原文

SSL3Padding SSL3.0协议定义的填补算法

参考资料

http://www.open-open.com/solution/view/1320502797546 http://www.cnblogs.com/AloneSword/p/3491466.html

转载于:https://my.oschina.net/u/2350108/blog/863319

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值