Skip to content
Switch branches/tags


Build Status

Angular webclient (with Linux, macOS and Windows desktop clients) for CTemplar's encrypted email service.


Development server

Run ng serve for a dev server. Navigate to http://localhost:4200/. The app will automatically reload if you change any of the source files.


Run ng build to build the project. The build artifacts will be stored in the dist/ directory. Use the -prod flag for a production build.

Build cross-platform Electron client

npm run build:electron
npm run pack -- --<platform> --<arch>


# Windows x64
npm run build:electron
npm run pack:electron -- --windows --x64


# macOS x64
npm run build:electron
npm run pack:electron -- --macos --x64


# Linux x64
npm run build:electron
npm run pack:electron -- --linux --x64


# Linux arm64
npm run build:electron
npm run pack:electron -- --linux --arm64

Then you can look for the executable in the new release/ directory.

For more information, execute npm run pack:electron -- --help or visit electron-builder documentation.


If you get the following error when running on Linux:

[10777:1211/] The SUID sandbox helper binary was found, but is not configured correctly. Rather than run without sandboxing I'm aborting now. You need to make sure that /tmp/.mount_CTemplR0XoE6/chrome-sandbox is owned by root and has mode 4755.

Try adding --no-sandbox when running the AppImage executable.


CTemplar uses bcrypt.js and OpenPGP.js for hashing and encryption.

Bug Bounties

Please, refer to our official publication regarding vulnerabilities diclosure and bug bounty questions.

Hash Password

CTemplar hashes every password before sending it to server for authentication or sign-up purposes. A unique salt is created from user's Username which is then used to hash the password using bcrypt.hashSync(password, salt) method.


CTemplar encrypts and decrypts contents of every email using user's public/private key pair which is generated during sign up process.

  • Public/Private Key pair is generated by openpgp.generateKey method using user's plain password as passphrase.

    const options = {
      userIds: [{ name: username, email: '' }],
      numBits: 4096,
      passphrase: password
  • Mail contents are encrypted by openpgp.encrypt method using receiver's Public Key.

    const options = {
        data: content,
        publicKeys: openpgp.key.readArmored(publicKey).keys
  • Mail contents are decrypted by openpgp.decrypt method using user's Private Key.

    let decryptedPrivateKey = openpgp.key.readArmored(privateKey).keys[0];
    const options = {
        message: openpgp.message.readArmored(encryptedContent),
        privateKeys: [decryptedPrivateKey]

Transparent build code

We host our build code publicly on github and we also provide the details on how to match checksum of code on github and the one we serve on our website. Find the details of build and how to calculate checksum here :


This project is still in early phase so bug reports via Issues and Pull Requests are welcome.


Apache License 2.0