title: How do I get Rust's openssl crate to decrypt data from the symmetric-encryption gem without the gibberish that Node Crypto automatically removes?
body: <p>I'm decrypting legacy data created by a Ruby on Rails application using the symmetric-encryption gem in Rust. See my earlier question <a href="https://stackoverflow.com/questions/47661306/">How do I decrypt data encrypted by Ruby&#39;s `symmetric-encryption` gem in another language?</a>.</p>
  
  <p>I've already implemented this in Node where the crypto library seems to know how to strip out gibberish in an encrypted string that Rust's <a href="https://crates.io/crates/openssl" rel="nofollow noreferrer"><code>openssl</code> crate</a> isn't stripping out (at least, the way I'm using it). I have already stripped out the PKCS7 padding and a header, yet it's still there. What is that gobbledygook, and how do I get Rust to remove it?</p>
  
  <p>The encrypted data began as plaintext with a fixed-size header, was encrypted using AES-128-CBC with PKCS7 padding, and was then Base64 encoded. Using Node, I can decrypt it correctly using the following code:</p>
  
  <pre><code>const crypto = require("crypto");
  
  const KEY = Buffer.from("1234567890ABCDEF");
  const IV = Buffer.from("1234567890ABCDEF");
  const CIPHERTEXT = Buffer.from("QEVuQwBAEACuPUPByDkk5jyNzQ3Wd3xTy2Isihz62XTLe1M5qKQrvw==", "base64");
  const HEADER_SIZE = 8;
  const ALGO = "aes-128-cbc";
  
  const decipher = crypto.createDecipheriv(ALGO, KEY, IV);
  
  decipher.update(CIPHERTEXT.slice(HEADER_SIZE));
  const result = decipher.final();
  
  console.log([...result]);
  console.log(result.toString());
  </code></pre>
  
  <p>The result is</p>
  
  <pre class="lang-none prettyprint-override"><code>[ 72, 97, 108, 102 ]
  Half
  </code></pre>
  
  <p>I'd prefer to use Rust for the application I'm writing. Using the <code>openssl</code> crate, I can decode the encrypted data, but there's a bunch of junk that Node's library knows how to strip but Rust isn't stripping automatically the way I'm using it:</p>
  
  <pre><code>extern crate base64;
  extern crate openssl;
  
  use openssl::symm::*;
  
  const KEY: &amp;'static [u8] = b"1234567890ABCDEF";
  const IV: &amp;'static [u8] = b"1234567890ABCDEF";
  const CIPHERTEXT: &amp;'static str = "QEVuQwBAEACuPUPByDkk5jyNzQ3Wd3xTy2Isihz62XTLe1M5qKQrvw==";
  const HEADER_SIZE: usize = 8;
  
  fn main() {
      let decoded = base64::decode(&amp;CIPHERTEXT).unwrap();
      let ciphertext = &amp;decoded[HEADER_SIZE..];
  
      let result = decrypt(Cipher::aes_128_cbc(), KEY, Some(IV), ciphertext).unwrap();
      println!("{:?}", result);
      println!("{:?}", String::from_utf8_lossy(&amp;result));
  }
  </code></pre>
  
  <p>Here the result is</p>
  
  <pre class="lang-none prettyprint-override"><code>[221, 75, 14, 215, 54, 120, 246, 222, 194, 208, 53, 68, 127, 190, 124, 8, 72, 97, 108, 102]
  "�K\u{e}�6x����5D\u{7f}�|\u{8}Half"
  </code></pre>
  
  <p>You can see that the last four bytes are correct, but that Node stripped out the preceding 16 bytes, as it appears it should have. I don't know what those bytes are.</p>
  
  <p>At first I thought the 16 bytes of gibberish were from attempting to decrypt the PKCS7 padding. But I can verify that the padding was already stripped out: if I create a <code>Crypter</code> following the example in the <code>openssl</code> crate's <a href="https://docs.rs/openssl/0.10.4/openssl/symm/struct.Crypter.html" rel="nofollow noreferrer">documentation</a>, but don't include the <code>truncate()</code> step, the resulting <code>Vec</code> has 12 consecutive <code>12</code>s&mdash;the PKCS7 padding&mdash;that were automatically removed. </p>
  
  <p>So the gibberish is not PKCS7 padding, but I don't know what it is or how to get rid of it using Rust.</p>
  
  <p>And to anticipate the Miranda warning about not futzing with crypto if I'm not an expert: this is not going to be used in production or to create data to put into production.</p>