Commit 7e5333e

mo <mo.khan@gmail.com>
2018-12-02 23:52:05
extract padding.
```text 5.2.1 Padding Since the data being encrypted is an arbitrary number of octets, it may not be a multiple of the block size. This is solved by padding the plain text up to the block size before encryption and unpadding after decryption. The padding algorithm is to calculate the smallest non-zero number of octets, say N, that must be suffixed to the plain text to bring it up to a multiple of the block size. We will assume the block size is B octets so N is in the range of 1 to B. Pad by suffixing the plain text with N-1 arbitrary pad bytes and a final byte whose value is N. On decryption, just take the last byte and, after sanity checking it, strip that many bytes from the end of the decrypted cipher text. For example, assume an 8 byte block size and plain text of 0x616263. The padded plain text would then be 0x616263????????05 where the "??" bytes can be any value. Similarly, plain text of 0x2122232425262728 would be padded to 0x2122232425262728??????????????08. ``` * https://www.w3.org/TR/xmlenc-core1/#sec-Alg-Block
1 parent 8d4021b
Changed files (3)
lib/xml/kit/crypto/symmetric_cipher.rb
@@ -31,10 +31,14 @@ module Xml
         end
 
         def decrypt(cipher_text)
-          default_decrypt(
+          result = default_decrypt(
             cipher_text[0...cipher.iv_len],
             cipher_text[cipher.iv_len..-1]
           )
+          return result if padding.nil?
+
+          padding_size = result.bytes.last
+          result[0...-padding_size]
         end
 
         protected
lib/xml/kit/decryption.rb
@@ -32,11 +32,11 @@ module Xml
       # @param hash [Hash] the XML document converted to a [Hash] using Hash.from_xml.
       def decrypt_hash(hash)
         encrypted_data = hash['EncryptedData']
-        symmetric_key = symmetric_key_from(encrypted_data)
-        cipher_value = encrypted_data['CipherData']['CipherValue']
-        cipher_text = Base64.decode64(cipher_value)
-        algorithm = encrypted_data['EncryptionMethod']['Algorithm']
-        to_plaintext(cipher_text, symmetric_key, algorithm)
+        to_plaintext(
+          Base64.decode64(encrypted_data['CipherData']['CipherValue']),
+          symmetric_key_from(encrypted_data),
+          encrypted_data['EncryptionMethod']['Algorithm']
+        )
       end
 
       # Decrypts an EncryptedData Nokogiri::XML::Element.
spec/xml/kit/crypto/symmetric_cipher_spec.rb
@@ -43,7 +43,7 @@ RSpec.describe ::Xml::Kit::Crypto::SymmetricCipher do
 
         specify do
           cipher_text = IO.read(encrypted_file, encoding: Encoding::ASCII_8BIT)
-          expect(subject.decrypt(cipher_text)).to include(secret)
+          expect(subject.decrypt(cipher_text)).to eql(secret)
         end
       end