sessioncrypt 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. #!/bin/sh
  2. #
  3. # This program automates the encrypt / decrypt this with openssl's AES-128-CBC
  4. # implementation.
  5. #
  6. # This is important because some people want to ban or outlaw encryption "apps"
  7. # like instant messengers. But what about raw, byte-by-byte encryption? Or
  8. # when we paste innocent-looking text in an online form?
  9. # Encryption will ALWAYS prevail!
  10. #
  11. # Copyright 2022 - kzimmermann. All rights reserved.
  12. #
  13. # This program is Free Software licensed under the terms and conditions of the
  14. # GNU GPL v3.0. See https://www.gnu.org/licenses for more information.
  15. #
  16. # Instructions:
  17. #
  18. # At first run, this program creates $HOME/.config/sessioncrypt.conf which
  19. # contains a random symmetric key. You can substitute the value there for your
  20. # own, but MAKE SURE IT IS ACTUALLY RANDOM!
  21. # Standard operation is to encrypt a plaintext using said key. Pass '-d' to
  22. # make it decrypt instead.
  23. #
  24. set -euo pipefail
  25. conf_file="$HOME/.config/sessioncrypt.conf"
  26. is_pipe=0
  27. # Test to see if you're receiving piped data. Thanks, SO.
  28. if [ -t 0 ]
  29. then
  30. is_pipe=0
  31. else
  32. is_pipe=1
  33. fi
  34. init() {
  35. # No parameters used.
  36. # Performs initiation sequences for Sessioncrypt program.
  37. # Will "reboot" configs if they already exist, so be careful.
  38. # Returns: nothing.
  39. echo "Creating config file at $conf_file"
  40. # Note the clobber right here ----------------v
  41. echo "# Configuration file for sessioncrypt." > "$conf_file"
  42. echo "# Lines beginning with a '#' are ignored." >> "$conf_file"
  43. echo "Generating random symmetric key..."
  44. rand_key=$(head -c30 /dev/urandom | base64)
  45. echo "KEY=$rand_key" >> "$conf_file"
  46. echo "Applying restrictive permissions to config file."
  47. # Yeah yeah, not really perfect, but obfuscating this would require gpg
  48. chmod 600 "$conf_file"
  49. }
  50. encrypt()
  51. {
  52. # $1 - plaintext to be converted
  53. # $2 - secret key
  54. # Returns: string IV:ciphertext, where IV is base64-encoded.
  55. IV=$(openssl rand 16 | xxd -ps)
  56. #CT=$(echo "$1" openssl enc -salt -aes-128-cbc -pbkdf2 -iv "$IV" -in "$1" -pass pass:"$2" -a |
  57. CT=$(echo "$1" | openssl enc -salt -aes-128-cbc -pbkdf2 -iv "$IV" -pass pass:"$2" -a |
  58. tr -d "\n")
  59. echo "$(printf "$IV" | base64):$CT"
  60. }
  61. decrypt()
  62. {
  63. # $1 - ciphertext to be decrypted, including IV.
  64. # $2 - secret key
  65. # Returns: string of plaintext
  66. IV=$(echo "$1" | cut -d ":" -f 1 | base64 -d) || {
  67. echo "Error: IV value not found!"
  68. exit 1
  69. }
  70. CT=$(echo "$1" | cut -d ":" -f 2)
  71. echo "$CT" | openssl enc -d -salt -aes-128-cbc -pbkdf2 -iv "$IV" -pass pass:"$2" -a
  72. }
  73. # Tester function. To make sure both functions are working correctly.
  74. dryrun() {
  75. input="roquefort cheese is delicious"
  76. echo "To encrypt: '$input'"
  77. printf "Password: "
  78. read -s key
  79. echo ""
  80. ciph=$(encrypt "$input" "$key")
  81. echo "---------"
  82. echo "Ciphertext: $ciph"
  83. printf "Plaintext: "
  84. decrypt "$ciph" "$key"
  85. }
  86. main()
  87. {
  88. if [ ! -f "$conf_file" ]
  89. then
  90. echo "Preparing for first run..."
  91. init
  92. fi
  93. # Parse key from config
  94. key=$(cat "$conf_file" | awk -F= '/KEY/ {print $2}')
  95. if [ "$#" -eq 0 ]
  96. then
  97. if [ $is_pipe -eq 1 ]
  98. then
  99. read -r plain
  100. else
  101. printf "Enter a text to encrypt: "
  102. read plain
  103. echo
  104. fi
  105. encrypt "$plain" "$key"
  106. exit 0
  107. fi
  108. if [ "$1" = "-i" ]
  109. then
  110. printf "Delete current configs (including key) and create new ones? (y/n) "
  111. read decision
  112. echo " "
  113. if [ "$decision" = "y" ]
  114. then
  115. init
  116. echo "Configurations re-created. Restart the program to use."
  117. exit 0
  118. else
  119. exit 0
  120. fi
  121. fi
  122. if [ "$1" = "-d" ]
  123. then
  124. if [ $is_pipe -eq 1 ]
  125. then
  126. read -r cipher
  127. else
  128. printf "Enter text for decryption: "
  129. read cipher
  130. echo
  131. fi
  132. decrypt "$cipher" "$key"
  133. elif [ "$1" = "-D" ]
  134. then
  135. dryrun
  136. exit 0
  137. elif [ "$1" = "-h" ]
  138. then
  139. echo "Usage: $(basename $0) [-d] [-D] [-h]"
  140. echo "Encrypts a message with AES-128-CBC"
  141. echo "Where:"
  142. echo " -d : decrypts text instead of encrypting"
  143. echo " -i : regen config (and keys)."
  144. echo " -D : dry-run (test)"
  145. echo " -h : this help text."
  146. exit 0
  147. else
  148. echo "Unknown option. Try -h"
  149. exit 1
  150. fi
  151. }
  152. main $*