go_server_rust_sdk/
crypto.rs1use aes_gcm::{Aes256Gcm, Key, Nonce, KeyInit};
7use aes_gcm::aead::Aead;
8use base64::{Engine as _, engine::general_purpose};
9use sha2::{Sha256, Digest};
10use serde_json::Value;
11use crate::error::{Result, SdkError};
12
13pub fn encrypt_data(data: &Value, key: &str) -> Result<String> {
26 let data_bytes = serde_json::to_vec(data)?;
28
29 let mut hasher = Sha256::new();
31 hasher.update(key.as_bytes());
32 let key_hash = hasher.finalize();
33
34 let cipher_key = Key::<Aes256Gcm>::from_slice(&key_hash);
36 let cipher = Aes256Gcm::new(cipher_key);
37
38 let mut iv_hasher = Sha256::new();
40 iv_hasher.update(key.as_bytes());
41 let iv_hash = iv_hasher.finalize();
42 let nonce = Nonce::from_slice(&iv_hash[..12]);
43
44 let ciphertext = cipher.encrypt(nonce, data_bytes.as_ref())
46 .map_err(|e| SdkError::Crypto(format!("Encryption failed: {:?}", e)))?;
47
48 Ok(general_purpose::STANDARD.encode(ciphertext))
50}
51
52pub fn salt_key(key: &str, salt: i32) -> Result<String> {
65 let salt_str = salt.to_string();
67 let mut hasher = Sha256::new();
68 hasher.update(salt_str.as_bytes());
69 let salt_hash = hasher.finalize();
70
71 let cipher_key = Key::<Aes256Gcm>::from_slice(&salt_hash);
73 let cipher = Aes256Gcm::new(cipher_key);
74
75 let mut iv_hasher = Sha256::new();
77 iv_hasher.update(salt_str.as_bytes());
78 let iv_hash = iv_hasher.finalize();
79 let nonce = Nonce::from_slice(&iv_hash[..12]);
80
81 let key_bytes = key.as_bytes();
83 let ciphertext = cipher.encrypt(nonce, key_bytes)
84 .map_err(|e| SdkError::Crypto(format!("Key encryption failed: {:?}", e)))?;
85
86 Ok(general_purpose::STANDARD.encode(ciphertext))
88}
89
90pub fn decrypt_data(encrypted_data: &str, key: &str) -> Result<Value> {
103 let ciphertext = general_purpose::STANDARD.decode(encrypted_data)?;
105
106 let mut hasher = Sha256::new();
108 hasher.update(key.as_bytes());
109 let key_hash = hasher.finalize();
110
111 let cipher_key = Key::<Aes256Gcm>::from_slice(&key_hash);
113 let cipher = Aes256Gcm::new(cipher_key);
114
115 let mut iv_hasher = Sha256::new();
117 iv_hasher.update(key.as_bytes());
118 let iv_hash = iv_hasher.finalize();
119 let nonce = Nonce::from_slice(&iv_hash[..12]);
120
121 let plaintext = cipher.decrypt(nonce, ciphertext.as_ref())
123 .map_err(|e| SdkError::Crypto(format!("Decryption failed: {:?}", e)))?;
124
125 let value: Value = serde_json::from_slice(&plaintext)?;
127 Ok(value)
128}
129
130pub fn unsalt_key(salted_key: &str, salt: i32) -> Result<String> {
143 let ciphertext = general_purpose::STANDARD.decode(salted_key)?;
145
146 let salt_str = salt.to_string();
148 let mut hasher = Sha256::new();
149 hasher.update(salt_str.as_bytes());
150 let salt_hash = hasher.finalize();
151
152 let cipher_key = Key::<Aes256Gcm>::from_slice(&salt_hash);
154 let cipher = Aes256Gcm::new(cipher_key);
155
156 let mut iv_hasher = Sha256::new();
158 iv_hasher.update(salt_str.as_bytes());
159 let iv_hash = iv_hasher.finalize();
160 let nonce = Nonce::from_slice(&iv_hash[..12]);
161
162 let plaintext = cipher.decrypt(nonce, ciphertext.as_ref())
164 .map_err(|e| SdkError::Crypto(format!("Key decryption failed: {:?}", e)))?;
165
166 String::from_utf8(plaintext)
168 .map_err(|e| SdkError::Crypto(format!("Invalid UTF-8 in decrypted key: {}", e)))
169}
170
171#[cfg(test)]
172mod tests {
173 use super::*;
174 use serde_json::json;
175
176 #[test]
177 fn test_encrypt_decrypt_data() {
178 let data = json!({
179 "message": "Hello, World!",
180 "number": 42
181 });
182 let key = "test-key-123";
183
184 let encrypted = encrypt_data(&data, key).unwrap();
185 let decrypted = decrypt_data(&encrypted, key).unwrap();
186
187 assert_eq!(data, decrypted);
188 }
189
190 #[test]
191 fn test_salt_unsalt_key() {
192 let key = "my-secret-key";
193 let salt = 123456;
194
195 let salted = salt_key(key, salt).unwrap();
196 let unsalted = unsalt_key(&salted, salt).unwrap();
197
198 assert_eq!(key, unsalted);
199 }
200
201 #[test]
202 fn test_deterministic_encryption() {
203 let data = json!({"test": "value"});
204 let key = "consistent-key";
205
206 let encrypted1 = encrypt_data(&data, key).unwrap();
207 let encrypted2 = encrypt_data(&data, key).unwrap();
208
209 assert_eq!(encrypted1, encrypted2);
211 }
212}