require 'spec_helper' require 'securerandom' class DummyClass include MySQLEncryption end describe 'MySQLEncryption' do before(:each) do @cut = DummyClass.new @key = SecureRandom.random_bytes(16) end context "Public Methods" do context '#mysql_encrypt' do it "should return nil if a nil string is specified" do expect(@cut.mysql_encrypt(nil, @key)).to be_nil end it "should call do_encrypt with a mysql'ized key and the string" do plain_text = "Plain Text" @cut.should_receive(:do_encrypt). with(plain_text, "abcdefghijklmnop"). and_return("encrypted_value") @cut.should_receive(:mysql_key). with("abcdefghijklmnop"). and_return("abcdefghijklmnop") expect(@cut.mysql_encrypt(plain_text, "abcdefghijklmnop")).to eq("encrypted_value") end end context '#mysql_decrypt' do it "should return nil if a nil string is specified" do expect(@cut.mysql_decrypt(nil, @key)).to be_nil end it "should call do_decrypt with a mysql'ized key and the string" do plain_text = "Plain Text" @cut.should_receive(:do_decrypt). with(plain_text, "abcdefghijklmnop"). and_return("encrypted_value") @cut.should_receive(:mysql_key). with("abcdefghijklmnop"). and_return("abcdefghijklmnop") expect(@cut.mysql_decrypt(plain_text, "abcdefghijklmnop")).to eq("encrypted_value") end end end context 'Protected Methods' do context '#aes' do it "should be able to encrypt, then decrypt a string using a specified key" do plain_text = 'plain text' encrypted_string = @cut.send(:aes, :encrypt, @key, plain_text) unencrypted_string = @cut.send(:aes, :decrypt, @key, encrypted_string) expect(unencrypted_string).to eq(plain_text) end end context '#do_en/decrypt' do it "should be able to encrypt, then decrypt a string using a specified key" do plain_text = 'plain text' encrypted_string = @cut.send(:do_encrypt, plain_text, @key) unencrypted_string = @cut.send(:do_decrypt, encrypted_string, @key) expect(unencrypted_string).to eq(plain_text) end end context '#mysql_key' do it "should return nil if a nil key was specified" do expect(@cut.send(:mysql_key, nil)).to be_nil end it "should return a final key that is 16 bytes long, each byte being the null-value if a blank key is specified" do expect(@cut.send(:mysql_key, "")).to eq("\0" * 16) end it "should right-pad a specified key with null bytes if the specified key is less than 16 bytes" do key = "abcdefghijklmop" # 15-byte key expect(@cut.send(:mysql_key, key)).to eq("abcdefghijklmop\0") end it "should simply echo back the same key if the specified key is 16 bytes" do key = "abcdefghijklmopq" # 16-byte key expect(@cut.send(:mysql_key, key)).to eq("abcdefghijklmopq") end it "should XOR the leading bytes of the resulting key with the trailing bytes of the specified key over 16 bytes" do key = "abcdefghijklmopqrs" # 18-byte key expect(@cut.send(:mysql_key, key)).to eq(("a".bytes.first ^ "r".bytes.first).chr + ("b".bytes.first ^ "s".bytes.first).chr + "cdefghijklmopq") end end end end