alex/cryptography — pull request #61 by dstufft (2013-09-12 01:42:01+00:00)
Title: [WIP] Add PKCS7 padding

- [ ] Documentation
- [ ] Tests
- [ ] Non Generator API?
- Currently requires b"".join() or similar to turn it into a string
- If we simply operate over strings then we can't use padding for very large datasets

Biggest question at the moment is what to do about the simpler non generator based use. One thought I had was to match what the input is. If you give us a string you get a string, if you give us a generator you get a generator back?

#### Streaming Input

```pycon
>>> import binascii
>>> import Crypto.Cipher.AES
>>> from cryptography.primitives.block import BlockCipher, ciphers, modes, padding
>>>
>>> def datamaker():
>>> for c in "11111111111111112222":
>>> yield c.encode("ascii")
>>>
>>>
>>> key = binascii.unhexlify(b"0" * 32)
>>> iv = binascii.unhexlify(b"0" * 32)
>>>
>>> cipher = BlockCipher(ciphers.AES(key), modes.CBC(iv))
>>> paes = Crypto.Cipher.AES.new(key, 2, iv)
>>> padder = padding.PKCS7(128)
>>>
>>> ciphered = b"".join(cipher.encrypt(block) for block in padder.pad(datamaker())) + cipher.finalize()
>>>
>>> "".join(padder.unpad(paes.decrypt(ciphered)))
'11111111111111112222'
```

#### Non Streaming Input

```pycon
>>> import binascii
>>> import Crypto.Cipher.AES
>>> from cryptography.primitives.block import BlockCipher, ciphers, modes, padding
>>>
>>> data = "11111111111111112222"
>>>
>>> key = binascii.unhexlify(b"0" * 32)
>>> iv = binascii.unhexlify(b"0" * 32)
>>>
>>> cipher = BlockCipher(ciphers.AES(key), modes.CBC(iv))
>>> paes = Crypto.Cipher.AES.new(key, 2, iv)
>>> padder = padding.PKCS7(128)
>>>
>>> ciphered = b"".join(cipher.encrypt(block) for block in padder.pad(data)) + cipher.finalize()
>>> "".join(padder.unpad(paes.decrypt(ciphered)))
'11111111111111112222'
```