simcrypt.go (2044B)
1 package main 2 3 import ( 4 "bytes" 5 "crypto/aes" 6 "crypto/cipher" 7 "crypto/rand" 8 "crypto/sha256" 9 "filippo.io/age" 10 "io" 11 ) 12 13 func sha256Sum(password []byte) []byte { 14 pwSha := sha256.Sum256(password) 15 return pwSha[:] 16 } 17 18 // Simple password-based encryption functions, 19 // AES-GCM (faster) and scrypt via `age` (more secure). 20 21 // Symmetric encryption for extra private key protection 22 func encrypt(plaintext, encryptionKey []byte) ([]byte, error) { 23 keyHash := sha256Sum(encryptionKey) 24 block, err := aes.NewCipher(keyHash) 25 if err != nil { 26 return nil, err 27 } 28 aesgcm, err := cipher.NewGCM(block) 29 if err != nil { 30 return nil, err 31 } 32 nonce := make([]byte, aesgcm.NonceSize()) 33 if _, err := io.ReadFull(rand.Reader, nonce); err != nil { 34 return nil, err 35 } 36 ciphertext := aesgcm.Seal(nonce, nonce, []byte(plaintext), nil) 37 return ciphertext, nil 38 } 39 40 func decrypt(cipherbundle, encryptionKey []byte) ([]byte, error) { 41 keyHash := sha256Sum(encryptionKey) 42 block, err := aes.NewCipher(keyHash) 43 if err != nil { 44 return nil, err 45 } 46 aesgcm, err := cipher.NewGCM(block) 47 if err != nil { 48 return nil, err 49 } 50 nonce := cipherbundle[:aesgcm.NonceSize()] 51 ciphertext := cipherbundle[aesgcm.NonceSize():] 52 return aesgcm.Open(nil, nonce, ciphertext, nil) 53 } 54 55 func ageEncrypt(plain, encryptionKey []byte) ([]byte, error) { 56 if len(plain) == 0 { 57 return []byte{}, nil 58 } 59 sr, err := age.NewScryptRecipient(string(encryptionKey)) 60 if err != nil { 61 return nil, err 62 } 63 var b bytes.Buffer 64 ew, err := age.Encrypt(&b, sr) 65 if err != nil { 66 return nil, err 67 } 68 _, err = ew.Write(plain) 69 if err != nil { 70 return nil, err 71 } 72 err = ew.Close() 73 return b.Bytes(), err 74 } 75 76 func ageDecrypt(cipher, encryptionKey []byte) ([]byte, error) { 77 if len(cipher) == 0 { 78 return []byte{}, nil 79 } 80 sr, err := age.NewScryptIdentity(string(encryptionKey)) 81 if err != nil { 82 return nil, err 83 } 84 var b bytes.Buffer 85 ew, err := age.Decrypt(&b, sr) 86 if err != nil { 87 return nil, err 88 } 89 _, err = ew.Read(cipher) 90 return b.Bytes(), err 91 } 92 93 func main() { 94 // TODO: read args etc... 95 }