diff --git a/lib/AccountManager/Tools.pm b/lib/AccountManager/Tools.pm
index e8292a6b77e5b9403b0e43f26e5b88f2e207780f..5b73f594a80388b5bdb7a4679f9888dba8dcd617 100644
--- a/lib/AccountManager/Tools.pm
+++ b/lib/AccountManager/Tools.pm
@@ -7,8 +7,39 @@ use Digest::SHA;
 use Digest::MD5;
 use Encode;
 use English qw(-no_match_vars);
+use List::MoreUtils qw(pairwise);
+use MIME::Base64;
 use Template;
 
+sub encrypt {
+    my ($string, $key) = @_;
+
+    my @string_chars = split(//, $string);
+    my @key_chars    = split(//, $key);
+
+    return encode_base64(otp(\@string_chars, \@key_chars));
+}
+
+sub decrypt {
+    my ($string, $key) = @_;
+
+    my @string_chars = split(//, decode_base64($string));
+    my @key_chars = split(//, $key);
+
+    return otp(\@string_chars, \@key_chars);
+}
+
+sub otp {
+    my ($string, $key) = @_;
+
+    my @chars =
+        pairwise { chr(ord($a) ^ ord($b)) }
+        @$string,
+        @$key;
+
+    return join('', @chars);
+}
+
 # get SHA256 hash for a string
 sub sha256_hash {
     my ($s) = @_;
diff --git a/t/tools.t b/t/tools.t
new file mode 100644
index 0000000000000000000000000000000000000000..c33216e862254547b86f41c311b1d63a5926a186
--- /dev/null
+++ b/t/tools.t
@@ -0,0 +1,23 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use English qw(-no_match_vars);
+use Test::More;
+
+use AccountManager::Tools;
+
+plan tests => 4;
+
+my $key    = AccountManager::Tools::generate_token(undef, 10);
+my $secret = AccountManager::Tools::generate_password();
+
+ok($key ne $secret, 'key and secret are random strings');
+ok(length($key) == length($secret), 'key and secret have same size'); 
+
+my $encrypted_secret = AccountManager::Tools::encrypt($secret, $key);
+ok($encrypted_secret ne $secret, 'crypted_secret and secret are differents');
+
+my $decrypted_secret = AccountManager::Tools::decrypt($encrypted_secret, $key);
+ok($decrypted_secret eq $secret, 'decrypted_secret and secret are equals');