somesocks / lua-lockbox

A collection of cryptographic primitives written in pure Lua
MIT License
357 stars 74 forks source link

pkcs7 padding problem #14

Closed yanming3 closed 1 year ago

yanming3 commented 8 years ago

The data encryped by lua-lockbox(ecb,pkcs7) can not be decryped by java(ecb,pkcs5),error message is :javax.crypto.BadPaddingException: Given final block not properly padded; It seems a padding error

somesocks commented 8 years ago

Hi yanming3,

Could you provide more information? The lua code you're using to encrypt, a test input, and the expected output?

yanming3 commented 7 years ago

Sorry for no reply for such a long time; Q1: lua-lockbox encrypt,java decrypt:

local String = require("string");
local Lockbox = require("lockbox"); 
Lockbox.ALLOW_INSECURE = true;
local String = require("string");
local Array = require("lockbox.util.array");
local Stream = require("lockbox.util.stream");
local ECBMode = require("lockbox.cipher.mode.ecb")
local PKCS7Padding = require("lockbox.padding.pkcs7");
local ZeroPadding = require("lockbox.padding.zero");
local DESCipher = require("lockbox.cipher.des");
local Base64 = require("lockbox.util.base64");

local content=[[{method:"getAppSummary",para:{"app_key":"ea76cfecec9b429f90b9156a52c706b1"}}]]
local cipher = ECBMode.Cipher().setKey(Array.fromString("abcd1234")).setBlockCipher(DESCipher).setPadding(PKCS7Padding);
local res = cipher.init().update(Stream.fromArray(Array.fromString(""))).update(Stream.fromArray(Array.fromString(content))).finish().asBytes()
local out= Base64.fromArray(res)
print(out)

output is "0uDQZI8obus+O2NCcei6QIaGJK+8F8+KzE3ncxNh2ft2h/I0gBYSjSr9zZciYyyuCljJfDT4mlYU9Q8knS7WQL8MRiHqf4l++tzGwXygrt8="

        String password = "abcd1234";
        DESKeySpec key = new DESKeySpec(password.getBytes());
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        Cipher encryptCipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
        encryptCipher.init(Cipher.DECRYPT_MODE, keyFactory.generateSecret(key));
        byte[] result = encryptCipher.doFinal(Base64.decodeBase64("0uDQZI8obus+O2NCcei6QIaGJK+8F8+KzE3ncxNh2ft2h/I0gBYSjSr9zZciYyyuCljJfDT4mlYU9Q8knS7WQL8MRiHqf4l++tzGwXygrt8="));
        System.out.println(new String(result));

output:

Exception in thread "main" javax.crypto.BadPaddingException: Given final block not properly padded
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:811)
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:676)
    at com.sun.crypto.provider.DESCipher.engineDoFinal(DESCipher.java:314)
    at javax.crypto.Cipher.doFinal(Cipher.java:2087)
    at CryptTest1.test3(CryptTest1.java:56)

if i change pkcs7.lua from

local paddingCount = blockSize - byteCount% blockSize;

to

local paddingCount = blockSize - byteCount% blockSize;

it works

yanming3 commented 7 years ago

Another question: When the data is encrypted by java and decrypted by lua-lockbox, should lua-lockbox must remove the padding data?

childepeng commented 7 years ago

I hava the same question.

I think pkcs7.lua should change from
local paddingCount = blockSize - ((byteCount -1) % blockSize) + 1; to local paddingCount = blockSize - (((byteCount -1) % blockSize) + 1);

boba1l0s2k9 commented 7 years ago

In file:

$PREFIX/share/lua/5.2/lockbox/padding/pkcs7.lua

Change from:

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

To:

local paddingCount = blockSize - byteCount % blockSize;

To make the padding compatible with OpenSSL. e.g. here's a test using the OpenSSL command line tool:

echo -n abcdefghijklmnopqrstuvwxyz0123456 | openssl enc -aes-256-cbc -K 0000000000000000000000000000000000000000000000000000000000000000 -iv 00000000000000000000000000000000 -nosalt | xxd | cut -f2-9 -d" " -s | tr -d " " | tr -d "\n" | tr "[a-z]" "[A-Z]"

Compare that output to this lockbox code:

print(
require("lockbox.cipher.mode.cbc").Cipher()
    .setKey(require("lockbox.util.array").fromHex("0000000000000000000000000000000000000000000000000000000000000000"))
    .setBlockCipher(require("lockbox.cipher.aes256"))
    .setPadding(require("lockbox.padding.pkcs7"))
    .init()
    .update(require("lockbox.util.stream").fromArray(require("lockbox.util.array").fromHex("00000000000000000000000000000000")))
    .update(require("lockbox.util.stream").fromArray(require("lockbox.util.array").fromString("abcdefghijklmnopqrstuvwxyz0123456")))
    .finish()
    .asHex()
);