AES - 关于PKCS5Padding与PKCS7Padding的区别

工作中,我们常常会遇到跨语言平台的加密解密算法的交互使用,特别是一些标准的加解密算法,都设计到数据块Block与填充算法的
问题,例如C#与JAVA中的常见的填充算法如下:

.Net中的填充算法:

成员名称说明
ANSIX923ANSIX923 填充字符串由一个字节序列组成,此字节序列的最后一个字节填充字节序列的长度,其余字节均填充数字零。 

下面的示例演示此模式的工作原理。假定块长度为

 8,数据长度为 9,则填充用八位字节数等于 7,数据等于 FF FF FF FF FF FF FF FF FF:

数据: FF FF FF FF FF FF FF FF FF

X923 填充: FF FF FF FF FF FF FF FF FF 00 00 00 00 00 00 07

ISO10126ISO10126 填充字符串由一个字节序列组成,此字节序列的最后一个字节填充字节序列的长度,其余字节填充随机数据。 

下面的示例演示此模式的工作原理。假定块长度为 8,数据长度为 9,则填充用八位字节数等于 7,数据等于 FF FF FF FF FF FF FF FF FF:

数据: FF FF FF FF FF FF FF FF FF

ISO10126 填充: FF FF FF FF FF FF FF FF FF 7D 2A 75 EF F8 EF 07

None不填充。 
PKCS7PKCS #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

Zeros填充字符串由设置为零的字节组成。 

JAVA中支持的填充算法(Cipher)有

Alg. Name Description
NoPadding No padding.
ISO10126Padding This padding for block ciphers is described in 5.2 Block Encryption Algorithms in the W3C's "XML Encryption Syntax and Processing" document.
OAEPPadding, OAEPWith<digest>And<mgf>Padding Optimal Asymmetric Encryption Padding scheme defined in PKCS1, where <digest> should be replaced by the message digest and <mgf> by the mask generation function. Examples: OAEPWithMD5AndMGF1Padding and OAEPWithSHA-512AndMGF1Padding.

If OAEPPadding is used, Cipher objects are initialized with a javax.crypto.spec.OAEPParameterSpec object to suppply values needed for OAEPPadding.
PKCS1Padding The padding scheme described in PKCS1, used with the RSA algorithm.
PKCS5Padding The padding scheme described in RSA Laboratories, "PKCS5: Password-Based Encryption Standard," version 1.5, November 1993.
SSL3Padding The padding scheme defined in the SSL Protocol Version 3.0, November 18, 1996, section 5.2.3.2 (CBC block cipher):
    block-ciphered struct {
	opaque content[SSLCompressed.length];
	opaque MAC[CipherSpec.hash_size];
	uint8 padding[
	    GenericBlockCipher.padding_length];
	uint8 padding_length;
    } GenericBlockCipher;
The size of an instance of a GenericBlockCipher must be a multiple of the block cipher's block length.

The padding length, which is always present, contributes to the padding, which implies that if:
    sizeof(content) + sizeof(MAC) % block_length = 0, 
padding has to be (block_length - 1) bytes long, because of the existence of padding_length.

This make the padding scheme similar (but not quite) to PKCS5Padding, where the padding length is encoded in the padding (and ranges from 1 to block_length). With the SSL scheme, the sizeof(padding) is encoded in the always present padding_length and therefore ranges from 0 to block_length-1.

简单对比之下发现,通用的有NoneISO10126两种填充法,实际上PKCS5Padding与PKCS7Padding基本上也是可以通用的。

通过研读参考资料下面的参考资料可以发现两者定义的区别:

  • [Def] PKCS #7: Cryptographic Message Syntax Standard,
    An RSA Laboratories Technical Note, Version 1.5. Revised November 1, 1993. http://www.cnblogs.com/midea0978/admin/ftp://ftp.rsa.com/pub/pkcs/ascii/pkcs-7.asc
  • [Inf] PKCS #5: Password-Based Encryption Standard,
    An RSA Laboratories Technical Note, Version 1.5. Revised November 1, 1993. http://www.cnblogs.com/midea0978/admin/ftp://ftp.rsa.com/pub/pkcs/ascii/pkcs-5.asc

    在PKCS5Padding中,明确定义Block的大小是8位,而在PKCS7Padding定义中,对于块的大小是不确定的,可以在1-255之间(块长度超出255的尚待研究),填充值的算法都是一样的:

    value=k - (l mod k)  ,K=块大小,l=数据长度,如果l=8, 则需要填充额外的8个byte的8

    在.net中,例如TripleDESCryptoServiceProvider ,默认BlockSize=64bits=8bytes,所以在这种情况下在PKCS5Padding=PKCS7Padding。

    如果在C#中自己定义了一个不是64bits的加密块大小,同时使用PKCS7Padding,那么在java中使用JDK标准的PKCS5Padding就不能解密了。

    JAVA Code示例

  • try {
        byte[] KEY_DATA = {1,8,-49,-31,77,90,10,121,-14,109,107,38,29,68,59,5,82,49,31,42,-25,67,96,15};
        Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
        SecretKeySpec key = new SecretKeySpec(KEY_DATA, "DESede");//生成加密解密需要的Key
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] res = cipher.doFinal(data.getBytes());
    } catch (Exception e) {
        e.printStackTrace();
    }

    C# Code示例
  • TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();
    des.Mode=CipherMode.ECB;
    des.Padding=PaddingMode.PKCS7;
    byte[] buffer =Encoding.Default.GetBytes("明文");
    MemoryStream stream = new MemoryStream();
    byte[] key=Convert.FromBase64String("AQjP4U1aCnnybWsmHUQ7BVIxHyrnQ2AP");
    CryptoStream encStream = new CryptoStream(stream, des.CreateEncryptor(key, null), CryptoStreamMode.Write);
    encStream.Write(buffer, 0, buffer.Length);
    encStream.FlushFinalBlock();
    byte[] res=stream.ToArray();
    Console.WriteLine("result:"+Convert.ToBase64String(res));

    参考http://www.users.zetnet.co.uk/hopwood/crypto/scan/cs.html#pad_PKCSPadding
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值