This open source web-app is designed to encrypt text (or "secret message"). It encrypts text using end-to-end (E2E) encryption so that only you or someone you trust who knows the password can read it.
Encryption and decryption works on your device. The app runs fully on the client side and can be used offline. Your data is not transferred anywhere or stored anywhere.
After encryption you get three self-contained parts:
These parts are necessary for decryption and are not stored in the app or on servers. For successful decryption, you will need this parts, password and iterations count that was used for encryption.
Looks | Description |
---|---|
Edit | Edit mode |
Markdown | Preview in markdown mode |
Set Password & Iterations | |
Encrypt. Press to encrypt | |
Decrypt. Press to decrypt | |
Manual enter: SALT, IV, DATA | |
Get QR-Code | |
Change textarea/preview wide |
Bundle link parts, or just follow whole link (or QR-Code) and make sure that in the address bar you have a link like: # + <SALT> : <IV> : <DATA>
.
Or use , to enter stuff manually.
The more iterations, the more load, the more time it takes to encrypt/decrypt, the stronger the encryption.
The iterations count is scaled as follows:
The iterations count cannot be lower than 1.
The text is compressed and converted into WordArray (32-bit word array):
const compressedMessage = LZString.compressToUint8Array(message);
const messageWordArray = CryptoJS.lib.WordArray.create(compressedMessage);
Creating key using the PBKDF2 algorithm based on a random generated salt, the entered password and the iterations count:
const generateKey = (password: string, salt: string, iterations: number): CryptoJS.lib.WordArray => {
return CryptoJS.PBKDF2(password, salt, {
keySize: 256 / 32,
iterations: iterations,
});
};
const salt = CryptoJS.lib.WordArray.random(128 / 8).toString();
const key = generateKey(password, salt, iterations);
Using the created key using the PBKDF2 algorithm and a random generated IV (Initialization Vector), the text is encrypted using the AES-256 encryption algorithm in CBC (Cipher Block Chaining) mode with PKCS7 padding:
const iv = CryptoJS.lib.WordArray.random(128 / 8);
const encrypted = CryptoJS.AES.encrypt(messageWordArray, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7,
});
An initialization vector (IV) is required to ensure that the encryption is unique even when the same key is used.
The output is a concatenated string in the format # + <SALT> : <IV> : <DATA>
:
return salt + ":" + iv.toString() + ":" + encrypted.toString();
Decryption occurs the same way, but in reverse.
This stuff (SALT & IV) needed to decrypt DATA.
6
qwerty
SALT, IV, DATA
SALT: 05f2cc85783d31c30d27fbdd3482eefe
IV: 5879f308fdda0f58bc2a2dc25e8f5a14
DATA: TyoQu72aMK1oXboMPA64IhjDXWkFo/tnywQZY6OWGQ99fcSSR3VrHnOrC35UNIvyajLkumEnDYuCYdn79vq0Wtf9J/tHhUZYDqf6+AFhLjGlWYv3P0Pyv6tC6reVuDBQ9gjz+1JWMi+GeRz6JFmoB65eA+f8+EO3MCQ2ko8KH5pvvDvgwZBbje8zHxXiFNchlB0dIdljxdY12yoCia1b6xX+KV/ihoEmXtRmhHptiBpyJDfbwzABxv0dxT4+OI+N0JCQmDSQF1iMpsmHUHzYCSVlVP4JRp8PzaHRkI+iJWIsXOD+FOoCJmCHOqwBBZ/jYLq277S0g8hr/TsBrVxcbpdnA4b6RluF+RdgUSfMYOhWeH5twwkceg6FfSNF2F+1b7GyzGDq5lxgMXewiaoOpGhaLgkNllKAQbG8rS31j7nknhM2dyURu3QCmTvwGnaTPMgVEHFO0pqoKxOKojwo4dR4Q4jsK6sxcHa50U/bPNi3LGd0H/hY4SKt1wLsTUiYuM2g/zRdAtg4GekJo0EhF3zWmITDNUjiqHYK+wiX5fRCIrlnnEvbMZjRziUDRX26nrQPs6fYMVAF5YgQVGzLlIs0uKO3EC0WyPqtNAVxuFBfLdygKeXnoCr2U7CwOMf0B7OY4I6NSpC5++YITcsZzQ==
SALT:
05f2cc85783d31c30d27fbdd3482eefe
IV:
5879f308fdda0f58bc2a2dc25e8f5a14
Encrypted Data (DATA):
TyoQu72aMK1oXboMPA64IhjDXWkFo/tnywQZY6OWGQ99fcSSR3VrHnOrC35UNIvyajLkumEnDYuCYdn79vq0Wtf9J/tHhUZYDqf6+AFhLjGlWYv3P0Pyv6tC6reVuDBQ9gjz+1JWMi+GeRz6JFmoB65eA+f8+EO3MCQ2ko8KH5pvvDvgwZBbje8zHxXiFNchlB0dIdljxdY12yoCia1b6xX+KV/ihoEmXtRmhHptiBpyJDfbwzABxv0dxT4+OI+N0JCQmDSQF1iMpsmHUHzYCSVlVP4JRp8PzaHRkI+iJWIsXOD+FOoCJmCHOqwBBZ/jYLq277S0g8hr/TsBrVxcbpdnA4b6RluF+RdgUSfMYOhWeH5twwkceg6FfSNF2F+1b7GyzGDq5lxgMXewiaoOpGhaLgkNllKAQbG8rS31j7nknhM2dyURu3QCmTvwGnaTPMgVEHFO0pqoKxOKojwo4dR4Q4jsK6sxcHa50U/bPNi3LGd0H/hY4SKt1wLsTUiYuM2g/zRdAtg4GekJo0EhF3zWmITDNUjiqHYK+wiX5fRCIrlnnEvbMZjRziUDRX26nrQPs6fYMVAF5YgQVGzLlIs0uKO3EC0WyPqtNAVxuFBfLdygKeXnoCr2U7CwOMf0B7OY4I6NSpC5++YITcsZzQ==
App runs on client.
Nothing stored in database.
Database does not exist.