-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcrypto_demo.go
More file actions
113 lines (97 loc) · 4.1 KB
/
crypto_demo.go
File metadata and controls
113 lines (97 loc) · 4.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// crypto_demo.go - Realistic demonstration of runtime/secret for ephemeral key protection
//
// This demo simulates a key exchange scenario where forward secrecy is critical.
// The ephemeral private key and shared secret are processed inside secret.Do(),
// ensuring they cannot be recovered from memory after the operation completes.
package main
import (
"crypto/rand"
"crypto/sha256"
"encoding/hex"
"fmt"
"runtime/secret"
)
// SessionKey represents the derived key that can safely leave the secret context
type SessionKey [32]byte
func main() {
fmt.Println("=== Ephemeral Key Exchange with Forward Secrecy ===")
fmt.Println()
// This will hold the session key derived inside secret.Do()
var sessionKey SessionKey
fmt.Println("Step 1: Entering protected context for key exchange...")
fmt.Printf(" secret.Enabled() = %v\n", secret.Enabled())
fmt.Println()
secret.Do(func() {
fmt.Println("Step 2: Inside secret.Do() - all operations are protected")
fmt.Printf(" secret.Enabled() = %v\n", secret.Enabled())
fmt.Println()
// Simulate ephemeral private key generation
// In real code, this would be the private part of an ECDH key pair
ephemeralPrivateKey := generateEphemeralKey()
fmt.Println("Step 3: Generated ephemeral private key (simulated)")
fmt.Printf(" Key bytes (first 8): %s...\n", hex.EncodeToString(ephemeralPrivateKey[:8]))
fmt.Println()
// Simulate receiving peer's public key and computing shared secret
// In real code: sharedSecret = ecdh.X25519().ECDH(privateKey, peerPublicKey)
peerPublicKey := simulatePeerPublicKey()
sharedSecret := computeSharedSecret(ephemeralPrivateKey, peerPublicKey)
fmt.Println("Step 4: Computed shared secret with peer (simulated ECDH)")
fmt.Printf(" Shared secret (first 8): %s...\n", hex.EncodeToString(sharedSecret[:8]))
fmt.Println()
// Derive session key from shared secret using HKDF-like derivation
sessionKey = deriveSessionKey(sharedSecret)
fmt.Println("Step 5: Derived session key (this is copied out)")
fmt.Printf(" Session key: %s\n", hex.EncodeToString(sessionKey[:]))
fmt.Println()
fmt.Println("Step 6: Exiting secret.Do() - ephemeral key and shared secret")
fmt.Println(" will be automatically erased from memory!")
})
fmt.Println()
fmt.Println("Step 7: Back in normal context")
fmt.Printf(" secret.Enabled() = %v\n", secret.Enabled())
fmt.Println()
fmt.Println(" The session key is available for use:")
fmt.Printf(" Session key: %s\n", hex.EncodeToString(sessionKey[:]))
fmt.Println()
fmt.Println("=== Forward Secrecy Achieved ===")
fmt.Println()
fmt.Println("Even if an attacker later gains access to system memory or core dumps,")
fmt.Println("they cannot recover:")
fmt.Println(" - The ephemeral private key")
fmt.Println(" - The shared secret")
fmt.Println()
fmt.Println("Only the derived session key remains, and without the ephemeral key,")
fmt.Println("past sessions cannot be decrypted (forward secrecy).")
}
// generateEphemeralKey simulates generating an ephemeral private key
func generateEphemeralKey() [32]byte {
var key [32]byte
if _, err := rand.Read(key[:]); err != nil {
panic("failed to generate random key: " + err.Error())
}
return key
}
// simulatePeerPublicKey simulates receiving a peer's public key
func simulatePeerPublicKey() [32]byte {
var key [32]byte
if _, err := rand.Read(key[:]); err != nil {
panic("failed to generate peer key: " + err.Error())
}
return key
}
// computeSharedSecret simulates ECDH shared secret computation
// In real code, use crypto/ecdh package
func computeSharedSecret(privateKey, peerPublic [32]byte) [32]byte {
// Simulate shared secret by combining keys (NOT real ECDH!)
combined := make([]byte, 64)
copy(combined[:32], privateKey[:])
copy(combined[32:], peerPublic[:])
return sha256.Sum256(combined)
}
// deriveSessionKey derives a session key from the shared secret
func deriveSessionKey(sharedSecret [32]byte) SessionKey {
// Simple derivation using SHA-256 with context
// In production, use proper HKDF
context := append([]byte("session-key-v1:"), sharedSecret[:]...)
return sha256.Sum256(context)
}