RCD Encryption package uses Emacs built-in encryption capabilities to encrypt and decrypt strings and regions.

It requires GNU Emacs package: rcd-utilities.el

To install this package, simply save the below embedded code, then install it with:

{M-x package-install-file RET rcd-encryption.el RET}

or you may download the file from: https://gnu.support/files/emacs/packages/rcd-encryption.el

and then install it with the Emacs command:

The embedded code follows:

;;; rcd-encryption.el --- RCD Encryption

;; Copyright (C) 2022 by Jean Louis

;; Author: Jean Louis <bugs@gnu.support>
;; Version: 0.1
;; Package-Requires: (rcd-utilities)
;; Keywords: tools
;; URL: https://gnu.support/gnu-emacs/packages/GNU-Emacs-Package-rcd-encryption-el-70898.html

;; This file is not part of GNU Emacs.

;; This program is free software: you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as
;; published by the Free Software Foundation, either version 3 of the
;; License, or (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful, but
;; WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
;; General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.

;;; Commentary:
;;
;; To encrypt a string:
;; (rcd-encrypt-decrypt "String" "Password")
;;
;; To encrypt a string with BASE64 encoding:
;; (rcd-encrypt-decrypt-base64 "String" "Password")
;;
;; To encrypt region:
;; {M-x rcd-encrypt-region-base64 RET}
;;
;; To decrypt region:
;; {M-x rcd-decrypt-region-base64 RET}
;;

;;; Change Log:

;;; Code:

(require 'rcd-utilities)

(defvar rcd-cipher 'AES-256-CFB8)
(defvar rcd-encryption-password nil)

(defun rcd-pad-to-multiple-bytes (string chunk-size)
  "Pad STRING to multiples of CHUNK-SIZE."
  (let* ((bytes (string-bytes string))
	 (multiple (* (ceiling bytes chunk-size) chunk-size)))
    (string-pad string multiple)))

(defun rcd-encrypt-decrypt (enc-dec password &optional decrypt cipher digest)
  "Encrypt or decrypt ENC-DEC with PASSWORD.

Default cipher is CHACHA20-64 or CIPHER as defined by the
function `gnutls-ciphers'.

Default digest is SHA512 or HASH as defined by the function
`gnutls-digests'.

Function encrypts by default, with DECRYPT being anything but
NIL, it will decrypt the ENC-DEC. "
  (let* ((cipher (or cipher "CHACHA20-64"))
	 (cipher-plist (alist-get cipher (gnutls-ciphers) nil nil 'string=))
	 (cipher-key-size (plist-get cipher-plist :cipher-keysize))
	 (key (rcd-pad-to-multiple-bytes password cipher-key-size))
	 (digest (or digest "SHA512"))
	 (hash (gnutls-hash-digest digest password))
	 (iv-size (plist-get cipher-plist :cipher-ivsize))
	 (iv (substring hash 0 iv-size))
	 (iv (string-pad iv iv-size))
	 (block-size (plist-get cipher-plist :cipher-blocksize))
	 (enc-dec (if decrypt enc-dec (rcd-pad-to-multiple-bytes enc-dec block-size))))
    (if decrypt
	(string-trim (car (gnutls-symmetric-decrypt cipher key iv enc-dec)))
      (car (gnutls-symmetric-encrypt cipher key iv enc-dec)))))

(defun rcd-encrypt-decrypt-base64 (enc-dec password &optional decrypt cipher digest no-line-break)
  "Use base64 encoding and decoding with encryption."
  (let* ((enc-dec (if decrypt (base64-decode-string enc-dec) enc-dec))
	 (enc-dec (rcd-encrypt-decrypt enc-dec password decrypt cipher digest))
	 (enc-dec (if decrypt enc-dec (base64-encode-string enc-dec no-line-break))))
    enc-dec))

(defun rcd-encryption-password (&optional prefix)
  "Ask for password and remember it for some time."
  (interactive "p")
  (if (or prefix (string-empty-p rcd-encryption-password) (< (length rcd-encryption-password) 1))
      (setq rcd-encryption-password (rcd-ask "RCD Encryption Password: "))
    rcd-encryption-password))

(defun rcd-encrypt-region-base64 (beg end)
  "Encrypt region."
  (interactive "r")
  (rcd-region-string-replace (rcd-encrypt-decrypt-base64 (rcd-region-string) (rcd-encryption-password) nil nil nil t)))

(defun rcd-decrypt-region-base64 (beg end)
  "Decrypt region"
  (interactive "r")
  (rcd-region-string-replace (rcd-encrypt-decrypt-base64 (rcd-region-string) (rcd-encryption-password) t nil nil t)))

;;; rcd-encryption.el ends here
{M-x package-install-file RET rcd-encryption.el RET}

This page has been published on: https://gnu.support/gnu-emacs/packages/GNU-Emacs-Package-rcd-encryption-el-70898.html