Skip to content

Commit d51fc08

Browse files
committed
Merge pull request chicks#2 from a1exsh/padding-option
Padding option
2 parents a0c571b + 777197d commit d51fc08

File tree

3 files changed

+38
-4
lines changed

3 files changed

+38
-4
lines changed

README.rdoc

+15
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,21 @@ Usage:
3333
AES.decrypt(plain, key, {:format => :plain})
3434
=> "A super secret message"
3535

36+
# By default data is padded to the nearest 16 bytes block. To turn
37+
# this off, you may use the :padding => false (or nil) option.
38+
#
39+
# In this mode however, the caller is required to pad the data. In
40+
# the following example the message is exactly 16 bytes long, so no
41+
# error aries.
42+
msg = AES.encrypt("A secret message", key, {:padding => false})
43+
=> "SnD+WIfEfjZRrl+WAM/9pw==$89sGGZsu973j8Gl6aXC8Uw=="
44+
45+
# Be sure to pass the same padding option when decrypting the
46+
# message, as it will fail if you try to decrypt unpadded data and
47+
# didn't specify :padding => false.
48+
AES.decrypt(msg, key, {:padding => false})
49+
=> "A secret message"
50+
3651
== Contributing to aes
3752

3853
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet

lib/aes/aes.rb

+12-4
Original file line numberDiff line numberDiff line change
@@ -122,11 +122,13 @@ def _encrypt
122122
# Merge init options with defaults
123123
def merge_options(opts)
124124
@options = {
125-
:format => :base_64,
126-
:cipher => "AES-256-CBC",
127-
:iv => nil,
125+
:format => :base_64,
126+
:cipher => "AES-256-CBC",
127+
:iv => nil,
128+
:padding => true, # use cipher padding by default
128129
}.merge! opts
129130
_handle_iv
131+
_handle_padding
130132
end
131133

132134
def _handle_iv
@@ -139,12 +141,18 @@ def _handle_iv
139141
end
140142
end
141143

144+
def _handle_padding
145+
# convert value to what OpenSSL module format expects
146+
@options[:padding] = @options[:padding] ? 1 : 0
147+
end
148+
142149
# Create a new cipher using the cipher type specified
143150
def _setup(action)
144151
@cipher ||= OpenSSL::Cipher::Cipher.new(@options[:cipher])
145152
# Toggles encryption mode
146153
@cipher.send(action)
154+
@cipher.padding = @options[:padding]
147155
@cipher.key = @key.unpack('a2'*32).map{|x| x.hex}.pack('c'*32)
148156
end
149157
end
150-
end
158+
end

test/test_aes.rb

+11
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,17 @@ class TestAES < Test::Unit::TestCase
1919
enc2 = AES.encrypt(msg, key, {:iv => iv})
2020
assert_equal enc1, enc2
2121
end
22+
23+
should "handle padding option" do
24+
key = "01234567890123456789012345678901"
25+
msg = "This is a message that nobody should ever see"
26+
# unpadded message length should be a multiple of cipher block
27+
# length (16 bytes)
28+
msg += " "*(16 - (msg.length % 16))
29+
30+
enc = AES.encrypt(msg, key, {:padding => false})
31+
assert_equal msg, AES.decrypt(enc, key, {:padding => false})
32+
end
2233

2334
should "generate a new key when AES#key" do
2435
assert_equal 32, AES.key.length

0 commit comments

Comments
 (0)