mirror of
https://github.com/tcsenpai/hmacrypt.git
synced 2025-06-06 02:45:21 +00:00
Implemented AES256
This commit is contained in:
parent
018bcadd34
commit
1e6baf57f6
38
README.md
38
README.md
@ -1,5 +1,19 @@
|
|||||||
# hmacrypt
|
# hmacrypt
|
||||||
encryption / decryption / signing / verifying using RSA and ECDSA a deterministic Key Derivation from password+hmac_secret by an hardware key.
|
encryption / decryption / signing / verifying using RSA, AES and ECDSA a deterministic Key Derivation from password+hmac_secret by an hardware key.
|
||||||
|
|
||||||
|
## Supported algorithms
|
||||||
|
|
||||||
|
- RSA (deterministic with keyfile, password and hw device)
|
||||||
|
- ECDSA (deterministic with keyfile, password and hw device)
|
||||||
|
- AES 256 (deterministic with keyfile, password and hw device)
|
||||||
|
|
||||||
|
## Tested devices
|
||||||
|
|
||||||
|
- Thetis FIDO2
|
||||||
|
|
||||||
|
### Should also work with
|
||||||
|
|
||||||
|
Any FIDO2/U2F key having hmac_secrets extension
|
||||||
|
|
||||||
## Requirements (BEFORE everything else) & Credits
|
## Requirements (BEFORE everything else) & Credits
|
||||||
|
|
||||||
@ -36,6 +50,7 @@ On Ubuntu 23.10 (untested on other platforms and flavors):
|
|||||||
|
|
||||||
- 2fa encryption/decryption using RSA deterministic Key Derivation
|
- 2fa encryption/decryption using RSA deterministic Key Derivation
|
||||||
- 2fa signing/verifying using ECDSA deterministic Key Derivation
|
- 2fa signing/verifying using ECDSA deterministic Key Derivation
|
||||||
|
- 2fa AES cipher encryption/decryption using SHA256
|
||||||
- Possibility to use the same or different keyfiles to enhance security
|
- Possibility to use the same or different keyfiles to enhance security
|
||||||
- Consequently, supports for a wide range of hardware keys as long as they are compatible with libfido2
|
- Consequently, supports for a wide range of hardware keys as long as they are compatible with libfido2
|
||||||
- Low footprint: requires just two (or three) python library and a single system library
|
- Low footprint: requires just two (or three) python library and a single system library
|
||||||
@ -96,6 +111,27 @@ Or the path you used for the library.
|
|||||||
*If you REALLY have to change the src directory name, please correct the various paths inside.*
|
*If you REALLY have to change the src directory name, please correct the various paths inside.*
|
||||||
|
|
||||||
|
|
||||||
|
#### encrypt_aes
|
||||||
|
|
||||||
|
Definition:
|
||||||
|
|
||||||
|
def encrypt_aes(message)
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
|
||||||
|
- message; data (string preferrable) to be encrypted
|
||||||
|
|
||||||
|
#### decrypt_aes
|
||||||
|
|
||||||
|
Definition:
|
||||||
|
|
||||||
|
def decrypt_aes(encrypted)
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
|
||||||
|
- encrypted; (usually) bytes to be decrypted
|
||||||
|
|
||||||
|
|
||||||
#### inferECDSAKeys
|
#### inferECDSAKeys
|
||||||
|
|
||||||
Definition:
|
Definition:
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import subprocess
|
import subprocess
|
||||||
from src.libs.seedable_rsa import decrypt, encrypt, generate_rsa_key
|
from src.libs.seedable_rsa import decrypt, encrypt, generate_rsa_key
|
||||||
from src.libs.seedable_ecdsa import generate_ecdsa_key, sign, verify
|
from src.libs.seedable_ecdsa import generate_ecdsa_key, sign, verify
|
||||||
|
from src.libs.seedable_aes import self_encrypt_aes, self_decrypt_aes
|
||||||
|
|
||||||
# INFO This method derives the HMAC secret from the hardware key and the stored secret
|
# INFO This method derives the HMAC secret from the hardware key and the stored secret
|
||||||
def getHMACSecret(keyfilePath="src/bins/.keyfile"):
|
def getHMACSecret(keyfilePath="src/bins/.keyfile"):
|
||||||
@ -15,6 +16,17 @@ def getHMACSecret(keyfilePath="src/bins/.keyfile"):
|
|||||||
hmac_secret = hmac_secret.strip()
|
hmac_secret = hmac_secret.strip()
|
||||||
return hmac_secret
|
return hmac_secret
|
||||||
|
|
||||||
|
# INFO The following methods are proxies to the AES methods
|
||||||
|
# NOTE The AES methods generate a cipher on the fly based on the getHMACSecret method
|
||||||
|
|
||||||
|
def encrypt_aes(message):
|
||||||
|
seed = getHMACSecret()
|
||||||
|
return self_encrypt_aes(seed, message)
|
||||||
|
|
||||||
|
def decrypt_aes(encrypted):
|
||||||
|
seed = getHMACSecret()
|
||||||
|
return self_decrypt_aes(seed, encrypted)
|
||||||
|
|
||||||
# INFO This method derives an ECDSA keypair from the stored secret and the hardware key
|
# INFO This method derives an ECDSA keypair from the stored secret and the hardware key
|
||||||
def inferECDSAKeys(hidePrivate=False, savePublic=False):
|
def inferECDSAKeys(hidePrivate=False, savePublic=False):
|
||||||
hmac_secret = getHMACSecret()
|
hmac_secret = getHMACSecret()
|
||||||
@ -108,12 +120,3 @@ def self_decrypt_file(filepath, outpath):
|
|||||||
|
|
||||||
|
|
||||||
# TODO LARGE FILES
|
# TODO LARGE FILES
|
||||||
|
|
||||||
|
|
||||||
# Self testing
|
|
||||||
if __name__ == "__main__":
|
|
||||||
private_key, public_key = inferRSAKeys()
|
|
||||||
secret = encrypt("secret message", public_key)
|
|
||||||
print(secret)
|
|
||||||
decrypted = decrypt(secret, private_key)
|
|
||||||
print(decrypted)
|
|
||||||
|
42
src/libs/seedable_aes.py
Normal file
42
src/libs/seedable_aes.py
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import base64
|
||||||
|
import hashlib
|
||||||
|
from Crypto import Random
|
||||||
|
from Crypto.Cipher import AES
|
||||||
|
|
||||||
|
class AESCipher(object):
|
||||||
|
|
||||||
|
def __init__(self, key):
|
||||||
|
self.bs = AES.block_size
|
||||||
|
self.key = hashlib.sha256(key.encode()).digest()
|
||||||
|
|
||||||
|
def encrypt(self, raw):
|
||||||
|
raw = self._pad(raw)
|
||||||
|
iv = Random.new().read(AES.block_size)
|
||||||
|
cipher = AES.new(self.key, AES.MODE_CBC, iv)
|
||||||
|
return base64.b64encode(iv + cipher.encrypt(raw.encode()))
|
||||||
|
|
||||||
|
def decrypt(self, enc):
|
||||||
|
enc = base64.b64decode(enc)
|
||||||
|
iv = enc[:AES.block_size]
|
||||||
|
cipher = AES.new(self.key, AES.MODE_CBC, iv)
|
||||||
|
return AESCipher._unpad(cipher.decrypt(enc[AES.block_size:])).decode('utf-8')
|
||||||
|
|
||||||
|
def _pad(self, s):
|
||||||
|
return s + (self.bs - len(s) % self.bs) * chr(self.bs - len(s) % self.bs)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _unpad(s):
|
||||||
|
return s[:-ord(s[len(s)-1:])]
|
||||||
|
|
||||||
|
# Implementable methods
|
||||||
|
# NOTE The cipher is initialized on the fly, so the seed is not stored
|
||||||
|
|
||||||
|
def self_encrypt_aes(seed, message):
|
||||||
|
cipher = AESCipher(seed)
|
||||||
|
encrypted = cipher.encrypt(message)
|
||||||
|
return encrypted
|
||||||
|
|
||||||
|
def self_decrypt_aes(seed, encrypted):
|
||||||
|
cipher = AESCipher(seed)
|
||||||
|
decrypted = cipher.decrypt(encrypted)
|
||||||
|
return decrypted
|
Loading…
x
Reference in New Issue
Block a user