package encrypter import ( "crypto/aes" "crypto/cipher" "crypto/rand" "crypto/rsa" "crypto/sha256" "encoding/base64" ) // AESKey type type AESKey []byte // EncryptedAESKey type type EncryptedAESKey []byte // NewAESKey func func NewAESKey() AESKey { bb := make([]byte, 32) rand.Read(bb) return AESKey(bb) } // ParseAESKey func func ParseAESKey(b []byte) AESKey { if len(b) != 32 { slog.Panicf("Invalid AESKey (%v)", len(b)) } return (AESKey)(b) } // EncryptKey func func (s *AESKey) EncryptKey(key *PublicKey) EncryptedAESKey { bb, err := key.Encrypt(([]byte)(*s)) if err != nil { panic(err) } return (EncryptedAESKey)(bb) } // Encrypt func func (s *AESKey) Encrypt(data []byte) (encrypted []byte, err error) { nonce := make([]byte, 12) rand.Read(nonce) block, err := aes.NewCipher(([]byte)(*s)) if err != nil { slog.Warnf("ERROR New cipher %v", err) return } gcm, err := cipher.NewGCM(block) if err != nil { slog.Warnf("ERROR New GCM %v", err) return } encrypted = append(nonce, gcm.Seal(nil, nonce, data, nil)...) return } // Decrypt func func (s *AESKey) Decrypt(data []byte) (plain []byte, err error) { block, err := aes.NewCipher(([]byte)(*s)) if err != nil { slog.Warnf("ERROR New cipher %v", err) return } gcm, err := cipher.NewGCM(block) if err != nil { slog.Warnf("ERROR New GCM %v", err) return } plain, err = gcm.Open(nil, data[:12], data[12:], nil) return } // MarshalJSON func func (s *AESKey) MarshalJSON() ([]byte, error) { return []byte("\"" + base64.RawURLEncoding.EncodeToString(([]byte)(*s)) + "\""), nil } func (s *AESKey) String() string { return base64.RawURLEncoding.EncodeToString(*s) } // Decrypt func func (s *EncryptedAESKey) Decrypt(key *PrivateKey) (AESKey, error) { bb, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, (*rsa.PrivateKey)(key), ([]byte)(*s), nil) if err != nil { slog.Warnf("ERROR Decrypt %v", err) return nil, err } return (AESKey)(bb), nil } // MarshalJSON func func (s *EncryptedAESKey) MarshalJSON() ([]byte, error) { return []byte("\"" + base64.RawURLEncoding.EncodeToString(([]byte)(*s)) + "\""), nil } func (s *EncryptedAESKey) String() string { return "\"" + base64.RawURLEncoding.EncodeToString(*s) + "\"" }