parent
033acae279
commit
b586d1e8ee
@ -1,2 +1,4 @@ |
|||||||
*.db |
*.db |
||||||
vaultClient |
vaultClient |
||||||
|
config.yaml |
||||||
|
*.pem |
||||||
|
|||||||
@ -0,0 +1,17 @@ |
|||||||
|
package main |
||||||
|
|
||||||
|
import ( |
||||||
|
"crypto/rand" |
||||||
|
"fmt" |
||||||
|
"golang.org/x/crypto/chacha20poly1305" |
||||||
|
) |
||||||
|
|
||||||
|
func main() { |
||||||
|
// Generate or use a pre-shared key (in real code, this should be properly managed)
|
||||||
|
key := make([]byte, chacha20poly1305.KeySize) |
||||||
|
if _, err := rand.Read(key); err != nil { |
||||||
|
// handle error
|
||||||
|
return |
||||||
|
} |
||||||
|
fmt.Printf("%x", key) |
||||||
|
} |
||||||
@ -0,0 +1,3 @@ |
|||||||
|
auth: |
||||||
|
ChaKey: "b107568bf716da40f5f17fea0e6608816020118d2c10b488ef9777b3d626126f" |
||||||
|
PEM: "encrypted_aes_key.pem" |
||||||
@ -1,25 +1,152 @@ |
|||||||
package main |
package main |
||||||
|
|
||||||
import ( |
import ( |
||||||
"crypto/rand" |
"crypto/aes" |
||||||
"encoding/hex" |
"crypto/cipher" |
||||||
"fmt" |
"crypto/rand" |
||||||
|
"encoding/pem" |
||||||
|
"errors" |
||||||
|
"fmt" |
||||||
|
"os" |
||||||
|
"flag" |
||||||
|
|
||||||
|
"golang.org/x/crypto/ssh/terminal" |
||||||
|
"golang.org/x/crypto/scrypt" |
||||||
) |
) |
||||||
|
|
||||||
func generateKey() ([]byte, error) { |
func main() { |
||||||
key := make([]byte, 16) |
keyPtr := flag.String("keyfile", "encrypted_aes_key.pem", "Enter keyfile") |
||||||
_, err := rand.Read(key) |
flag.Parse() |
||||||
if err != nil { |
|
||||||
return nil, err |
if *keyPtr == "" { |
||||||
|
fmt.Print("Please enter a keyfile") |
||||||
|
return |
||||||
} |
} |
||||||
return key, nil |
|
||||||
|
// Generate a new AES-256 key
|
||||||
|
key, err := generateAESKey(32) // 32 bytes = 256 bits
|
||||||
|
if err != nil { |
||||||
|
fmt.Printf("Error generating AES key: %v\n", err) |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
// Prompt for passphrase
|
||||||
|
print("Enter passphrase: ") |
||||||
|
pass, _ := terminal.ReadPassword(0) // Hides input
|
||||||
|
password := string(pass) |
||||||
|
|
||||||
|
// Encrypt and PEM encode the key
|
||||||
|
pemBlock, err := encryptKeyToPEM(key, password) |
||||||
|
if err != nil { |
||||||
|
fmt.Printf("Error encrypting key: %v\n", err) |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
// Save to file
|
||||||
|
err = os.WriteFile(*keyPtr, pem.EncodeToMemory(pemBlock), 0600) |
||||||
|
if err != nil { |
||||||
|
fmt.Printf("Error writing PEM file: %v\n", err) |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
fmt.Printf("Successfully generated and password-protected AES key in %s", *keyPtr) |
||||||
} |
} |
||||||
|
|
||||||
func main() { |
// generateAESKey creates a new random AES key of specified size
|
||||||
key, err := generateKey() |
func generateAESKey(size int) ([]byte, error) { |
||||||
if err != nil { |
key := make([]byte, size) |
||||||
panic(err) |
_, err := rand.Read(key) |
||||||
} |
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
return key, nil |
||||||
|
} |
||||||
|
|
||||||
|
// encryptKeyToPEM encrypts the key with a password and returns a PEM block
|
||||||
|
func encryptKeyToPEM(key []byte, password string) (*pem.Block, error) { |
||||||
|
// Convert password to suitable encryption key
|
||||||
|
salt := make([]byte, 16) |
||||||
|
if _, err := rand.Read(salt); err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
|
||||||
|
// Use scrypt for key derivation (better than PBKDF2)
|
||||||
|
// N: CPU/memory cost, r: block size, p: parallelization
|
||||||
|
encryptionKey, err := scrypt.Key([]byte(password), salt, 32768, 8, 1, 32) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
|
||||||
|
// Generate a random IV
|
||||||
|
iv := make([]byte, aes.BlockSize) |
||||||
|
if _, err := rand.Read(iv); err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
|
||||||
|
// Encrypt the key
|
||||||
|
block, err := aes.NewCipher(encryptionKey) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
|
||||||
|
encrypted := make([]byte, len(key)) |
||||||
|
stream := cipher.NewCFBEncrypter(block, iv) |
||||||
|
stream.XORKeyStream(encrypted, key) |
||||||
|
|
||||||
|
// Create PEM block
|
||||||
|
pemBlock := &pem.Block{ |
||||||
|
Type: "ENCRYPTED AES KEY", |
||||||
|
Headers: map[string]string{ |
||||||
|
"Key-Derivation": "scrypt", |
||||||
|
"SALT": fmt.Sprintf("%x", salt), |
||||||
|
"IV": fmt.Sprintf("%x", iv), |
||||||
|
"Key-Size": fmt.Sprintf("%d", len(key)*8), |
||||||
|
}, |
||||||
|
Bytes: encrypted, |
||||||
|
} |
||||||
|
|
||||||
|
return pemBlock, nil |
||||||
|
} |
||||||
|
|
||||||
|
// hexStringToBytes converts a hex string to bytes
|
||||||
|
func hexStringToBytes(hexStr string) ([]byte, error) { |
||||||
|
if len(hexStr)%2 != 0 { |
||||||
|
return nil, errors.New("hex string length must be even") |
||||||
|
} |
||||||
|
bytes := make([]byte, len(hexStr)/2) |
||||||
|
for i := 0; i < len(hexStr); i += 2 { |
||||||
|
b, err := hexByte(hexStr[i], hexStr[i+1]) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
bytes[i/2] = b |
||||||
|
} |
||||||
|
return bytes, nil |
||||||
|
} |
||||||
|
|
||||||
|
// hexByte converts two hex characters to a byte
|
||||||
|
func hexByte(a, b byte) (byte, error) { |
||||||
|
high, err := hexDigitToByte(a) |
||||||
|
if err != nil { |
||||||
|
return 0, err |
||||||
|
} |
||||||
|
low, err := hexDigitToByte(b) |
||||||
|
if err != nil { |
||||||
|
return 0, err |
||||||
|
} |
||||||
|
return (high << 4) | low, nil |
||||||
|
} |
||||||
|
|
||||||
fmt.Println("Generated 32-byte key (hex):", hex.EncodeToString(key)) |
// hexDigitToByte converts a single hex character to its byte value
|
||||||
|
func hexDigitToByte(c byte) (byte, error) { |
||||||
|
switch { |
||||||
|
case '0' <= c && c <= '9': |
||||||
|
return c - '0', nil |
||||||
|
case 'a' <= c && c <= 'f': |
||||||
|
return c - 'a' + 10, nil |
||||||
|
case 'A' <= c && c <= 'F': |
||||||
|
return c - 'A' + 10, nil |
||||||
|
default: |
||||||
|
return 0, fmt.Errorf("invalid hex digit %c", c) |
||||||
|
} |
||||||
} |
} |
||||||
|
|||||||
Loading…
Reference in new issue