package securestring import ( "errors" "github.com/awnumar/memguard" ) // SecureString is used to store a string securely in memory. // It uses memguard to protect sensitive data like passwords, API keys, etc. // from being exposed in memory dumps, swap files, or other memory scanning attacks. type SecureString struct { buffer *memguard.LockedBuffer } // NewSecureString creates a new SecureString instance from the given string. // The original string should be cleared/wiped after creating SecureString to ensure // the sensitive data is only stored in the secure buffer. func NewSecureString(s string) (*SecureString, error) { if len(s) == 0 { return nil, errors.New("string cannot be empty") } // Use memguard's built-in method for creating from bytes buffer := memguard.NewBufferFromBytes([]byte(s)) // Check if buffer was created successfully if buffer == nil { return nil, errors.New("failed to create buffer") } return &SecureString{buffer: buffer}, nil } // String returns the securely stored string. // WARNING: The returned string is a copy and will not be protected by memguard. // Use this method carefully and wipe the string after use if possible. func (ss *SecureString) String() string { if ss.buffer == nil { return "" } if !ss.buffer.IsAlive() { return "" } return ss.buffer.String() } // Bytes returns the byte representation of the securely stored string. // WARNING: The returned bytes are still protected by memguard, but any copies // made from this slice will not be protected. Use with caution. func (ss *SecureString) Bytes() []byte { if ss.buffer == nil { return nil } if !ss.buffer.IsAlive() { return nil } return ss.buffer.Bytes() } // Wipe removes the string from memory and makes it unrecoverable. // After calling Wipe, the SecureString instance should not be used. func (ss *SecureString) Wipe() error { if ss.buffer != nil { if ss.buffer.IsAlive() { ss.buffer.Destroy() } } ss.buffer = nil return nil }