Create and store a keyset in plaintext

The following examples show how to create a keyset with a single key and store it in plaintext on disk.

Tinkey

 tinkey create-keyset \
  --key-template AES128_GCM \
  --out-format json \
  --out aead_keyset.json 

Java

 package 
  
 cleartextkeyset 
 ; 
 import static 
  
 java.nio.charset.StandardCharsets.UTF_8 
 ; 
 import 
  
 com.google.crypto.tink.Aead 
 ; 
 import 
  
 com.google.crypto.tink.InsecureSecretKeyAccess 
 ; 
 import 
  
 com.google.crypto.tink.KeysetHandle 
 ; 
 import 
  
 com.google.crypto.tink.RegistryConfiguration 
 ; 
 import 
  
 com.google.crypto.tink.TinkJsonProtoKeysetFormat 
 ; 
 import 
  
 com.google.crypto.tink.aead.AeadConfig 
 ; 
 import 
  
 com.google.crypto.tink.aead.PredefinedAeadParameters 
 ; 
 import 
  
 java.nio.file.Files 
 ; 
 import 
  
 java.nio.file.Path 
 ; 
 import 
  
 java.nio.file.Paths 
 ; 
 /** 
 * A command-line utility for generating, storing and using AES128_GCM keysets. 
 * 
 * <h1>WARNING: Loading a Keyset from disk is often a security problem -- hence this needs {@code 
 * InsecureSecretKeyAccess.get()}. 
 * 
 * <p>It requires the following arguments: 
 * 
 * <ul> 
 *   <li>mode: Can be "generate", "encrypt" or "decrypt". If mode is "generate" it will generate, 
 *       encrypt a keyset, store it in key-file. If mode is "encrypt" or "decrypt" it will read and 
 *       decrypt an keyset from key-file, and use it to encrypt or decrypt input-file. 
 *   <li>key-file: Read the encrypted key material from this file. 
 *   <li>input-file: If mode is "encrypt" or "decrypt", read the input from this file. 
 *   <li>output-file: If mode is "encrypt" or "decrypt", write the result to this file. 
 */ 
 public 
  
 final 
  
 class 
 CleartextKeysetExample 
  
 { 
  
 private 
  
 static 
  
 final 
  
 String 
  
 MODE_ENCRYPT 
  
 = 
  
 "encrypt" 
 ; 
  
 private 
  
 static 
  
 final 
  
 String 
  
 MODE_DECRYPT 
  
 = 
  
 "decrypt" 
 ; 
  
 private 
  
 static 
  
 final 
  
 String 
  
 MODE_GENERATE 
  
 = 
  
 "generate" 
 ; 
  
 private 
  
 static 
  
 final 
  
 byte 
 [] 
  
 EMPTY_ASSOCIATED_DATA 
  
 = 
  
 new 
  
 byte 
 [ 
 0 
 ] 
 ; 
  
 public 
  
 static 
  
 void 
  
 main 
 ( 
 String 
 [] 
  
 args 
 ) 
  
 throws 
  
 Exception 
  
 { 
  
 if 
  
 ( 
 args 
 . 
 length 
  
 != 
  
 2 
 && 
 args 
 . 
 length 
  
 != 
  
 4 
 ) 
  
 { 
  
 System 
 . 
 err 
 . 
 printf 
 ( 
 "Expected 2 or 4 parameters, got %d\n" 
 , 
  
 args 
 . 
 length 
 ); 
  
 System 
 . 
 err 
 . 
 println 
 ( 
  
 "Usage: java CleartextKeysetExample generate/encrypt/decrypt key-file input-file" 
  
 + 
  
 " output-file" 
 ); 
  
 System 
 . 
 exit 
 ( 
 1 
 ); 
  
 } 
  
 String 
  
 mode 
  
 = 
  
 args 
 [ 
 0 
 ] 
 ; 
  
 if 
  
 ( 
 ! 
 MODE_ENCRYPT 
 . 
 equals 
 ( 
 mode 
 ) 
 && 
 ! 
 MODE_DECRYPT 
 . 
 equals 
 ( 
 mode 
 ) 
 && 
 ! 
 MODE_GENERATE 
 . 
 equals 
 ( 
 mode 
 )) 
  
 { 
  
 System 
 . 
 err 
 . 
 print 
 ( 
 "The first argument should be either encrypt, decrypt or generate" 
 ); 
  
 System 
 . 
 exit 
 ( 
 1 
 ); 
  
 } 
  
 Path 
  
 keyFile 
  
 = 
  
 Paths 
 . 
 get 
 ( 
 args 
 [ 
 1 
 ] 
 ); 
  
 // Initialise Tink: register all AEAD key types with the Tink runtime 
  
 AeadConfig 
 . 
 register 
 (); 
  
 if 
  
 ( 
 MODE_GENERATE 
 . 
 equals 
 ( 
 mode 
 )) 
  
 { 
  
 KeysetHandle 
  
 handle 
  
 = 
  
 KeysetHandle 
 . 
 generateNew 
 ( 
 PredefinedAeadParameters 
 . 
 AES128_GCM 
 ); 
  
 String 
  
 serializedKeyset 
  
 = 
  
 TinkJsonProtoKeysetFormat 
 . 
 serializeKeyset 
 ( 
 handle 
 , 
  
 InsecureSecretKeyAccess 
 . 
 get 
 ()); 
  
 Files 
 . 
 write 
 ( 
 keyFile 
 , 
  
 serializedKeyset 
 . 
 getBytes 
 ( 
 UTF_8 
 )); 
  
 return 
 ; 
  
 } 
  
 // Use the primitive to encrypt/decrypt files 
  
 // Read the keyset from disk 
  
 String 
  
 serializedKeyset 
  
 = 
  
 new 
  
 String 
 ( 
 Files 
 . 
 readAllBytes 
 ( 
 keyFile 
 ), 
  
 UTF_8 
 ); 
  
 KeysetHandle 
  
 handle 
  
 = 
  
 TinkJsonProtoKeysetFormat 
 . 
 parseKeyset 
 ( 
 serializedKeyset 
 , 
  
 InsecureSecretKeyAccess 
 . 
 get 
 ()); 
  
 // Get the primitive 
  
 Aead 
  
 aead 
  
 = 
  
 handle 
 . 
 getPrimitive 
 ( 
 RegistryConfiguration 
 . 
 get 
 (), 
  
 Aead 
 . 
 class 
 ); 
  
 byte 
 [] 
  
 input 
  
 = 
  
 Files 
 . 
 readAllBytes 
 ( 
 Paths 
 . 
 get 
 ( 
 args 
 [ 
 2 
 ] 
 )); 
  
 Path 
  
 outputFile 
  
 = 
  
 Paths 
 . 
 get 
 ( 
 args 
 [ 
 3 
 ] 
 ); 
  
 if 
  
 ( 
 MODE_ENCRYPT 
 . 
 equals 
 ( 
 mode 
 )) 
  
 { 
  
 byte 
 [] 
  
 ciphertext 
  
 = 
  
 aead 
 . 
 encrypt 
 ( 
 input 
 , 
  
 EMPTY_ASSOCIATED_DATA 
 ); 
  
 Files 
 . 
 write 
 ( 
 outputFile 
 , 
  
 ciphertext 
 ); 
  
 } 
  
 else 
  
 if 
  
 ( 
 MODE_DECRYPT 
 . 
 equals 
 ( 
 mode 
 )) 
  
 { 
  
 byte 
 [] 
  
 plaintext 
  
 = 
  
 aead 
 . 
 decrypt 
 ( 
 input 
 , 
  
 EMPTY_ASSOCIATED_DATA 
 ); 
  
 Files 
 . 
 write 
 ( 
 outputFile 
 , 
  
 plaintext 
 ); 
  
 } 
  
 } 
  
 private 
  
 CleartextKeysetExample 
 () 
  
 {} 
 } 
  

Go

 import 
  
 ( 
  
 "bytes" 
  
 "fmt" 
  
 "log" 
  
 "github.com/tink-crypto/tink-go/v2/aead" 
  
 "github.com/tink-crypto/tink-go/v2/insecurecleartextkeyset" 
  
 "github.com/tink-crypto/tink-go/v2/keyset" 
 ) 
 func 
  
 Example_cleartextKeysetInBinary 
 () 
  
 { 
  
 // Generate a new keyset handle for the primitive we want to use. 
  
 handle 
 , 
  
 err 
  
 := 
  
 keyset 
 . 
 NewHandle 
 ( 
 aead 
 . 
 AES256GCMKeyTemplate 
 ()) 
  
 if 
  
 err 
  
 != 
  
 nil 
  
 { 
  
 log 
 . 
 Fatal 
 ( 
 err 
 ) 
  
 } 
  
 // Serialize the keyset. 
  
 buff 
  
 := 
  
& bytes 
 . 
 Buffer 
 {} 
  
 err 
  
 = 
  
 insecurecleartextkeyset 
 . 
 Write 
 ( 
 handle 
 , 
  
 keyset 
 . 
 NewBinaryWriter 
 ( 
 buff 
 )) 
  
 if 
  
 err 
  
 != 
  
 nil 
  
 { 
  
 log 
 . 
 Fatal 
 ( 
 err 
 ) 
  
 } 
  
 serializedKeyset 
  
 := 
  
 buff 
 . 
 Bytes 
 () 
  
 // serializedKeyset can now be stored at a secure location. 
  
 // WARNING: Storing the keyset in cleartext to disk is not recommended! 
  
 // Parse the keyset. 
  
 parsedHandle 
 , 
  
 err 
  
 := 
  
 insecurecleartextkeyset 
 . 
 Read 
 ( 
  
 keyset 
 . 
 NewBinaryReader 
 ( 
 bytes 
 . 
 NewBuffer 
 ( 
 serializedKeyset 
 ))) 
  
 if 
  
 err 
  
 != 
  
 nil 
  
 { 
  
 log 
 . 
 Fatal 
 ( 
 err 
 ) 
  
 } 
  
 // Get the primitive. 
  
 primitive 
 , 
  
 err 
  
 := 
  
 aead 
 . 
 New 
 ( 
 parsedHandle 
 ) 
  
 if 
  
 err 
  
 != 
  
 nil 
  
 { 
  
 log 
 . 
 Fatal 
 ( 
 err 
 ) 
  
 } 
  
 // Use the primitive. 
  
 plaintext 
  
 := 
  
 [] 
 byte 
 ( 
 "message" 
 ) 
  
 associatedData 
  
 := 
  
 [] 
 byte 
 ( 
 "example encryption" 
 ) 
  
 ciphertext 
 , 
  
 err 
  
 := 
  
 primitive 
 . 
 Encrypt 
 ( 
 plaintext 
 , 
  
 associatedData 
 ) 
  
 if 
  
 err 
  
 != 
  
 nil 
  
 { 
  
 log 
 . 
 Fatal 
 ( 
 err 
 ) 
  
 } 
  
 decrypted 
 , 
  
 err 
  
 := 
  
 primitive 
 . 
 Decrypt 
 ( 
 ciphertext 
 , 
  
 associatedData 
 ) 
  
 if 
  
 err 
  
 != 
  
 nil 
  
 { 
  
 log 
 . 
 Fatal 
 ( 
 err 
 ) 
  
 } 
  
 fmt 
 . 
 Println 
 ( 
 string 
 ( 
 decrypted 
 )) 
  
 // Output: message 
 } 
  

Python

 """A command-line utility for generating, storing and using cleartext AES128_GCM keysets. 
 It loads cleartext keys from disk - this is not recommended! 
 """ 
 from 
  
 absl 
  
 import 
  
 app 
 from 
  
 absl 
  
 import 
  
 flags 
 from 
  
 absl 
  
 import 
  
 logging 
 import 
  
 tink 
 from 
  
 tink 
  
 import 
  
 aead 
 from 
  
 tink 
  
 import 
  
 secret_key_access 
 FLAGS 
  
 = 
  
 flags 
 . 
 FLAGS 
 flags 
 . 
 DEFINE_enum 
 ( 
 ' 
 mode 
 ' 
 , 
  
 None 
 , 
  
 [ 
 ' 
 generate 
 ' 
 , 
  
 ' 
 encrypt 
 ' 
 , 
  
 ' 
 decrypt 
 ' 
 ], 
  
 ' 
 The 
  
 operation 
  
 to 
  
 perform 
 . 
 ' 
 ) 
 flags 
 . 
 DEFINE_string 
 ( 
 ' 
 keyset_path 
 ' 
 , 
  
 None 
 , 
  
 ' 
 Path 
  
 to 
  
 the 
  
 keyset 
  
 used 
  
 for 
  
 encryption 
 . 
 ' 
 ) 
 flags 
 . 
 DEFINE_string 
 ( 
 ' 
 input_path 
 ' 
 , 
  
 None 
 , 
  
 ' 
 Path 
  
 to 
  
 the 
  
 input 
  
 file 
 . 
 ' 
 ) 
 flags 
 . 
 DEFINE_string 
 ( 
 ' 
 output_path 
 ' 
 , 
  
 None 
 , 
  
 ' 
 Path 
  
 to 
  
 the 
  
 output 
  
 file 
 . 
 ' 
 ) 
 def 
  
 main 
 ( 
 argv 
 ): 
  
 del 
  
 argv 
  
 # 
  
 Unused 
 . 
  
 # 
  
 Initialise 
  
 Tink 
  
 aead 
 . 
 register 
 () 
  
 if 
  
 FLAGS 
 . 
 mode 
  
 == 
  
 ' 
 generate 
 ' 
 : 
  
 # 
  
 Generate 
  
 a 
  
 new 
  
 keyset 
  
 try 
 : 
  
 key_template 
  
 = 
  
 aead 
 . 
 aead_key_templates 
 . 
 AES128_GCM 
  
 keyset_handle 
  
 = 
  
 tink 
 . 
 new_keyset_handle 
 ( 
 key_template 
 ) 
  
 except 
  
 tink 
 . 
 TinkError 
  
 as 
  
 e 
 : 
  
 logging 
 . 
 exception 
 ( 
 ' 
 Error 
  
 creating 
  
 primitive 
 : 
  
 % 
 s 
 ' 
 , 
  
 e 
 ) 
  
 return 
  
 1 
  
 with 
  
 open 
 ( 
 FLAGS 
 . 
 keyset_path 
 , 
  
 ' 
 wt 
 ' 
 ) 
  
 as 
  
 keyset_file 
 : 
  
 try 
 : 
  
 serialized_keyset 
  
 = 
  
 tink 
 . 
 json_proto_keyset_format 
 . 
 serialize 
 ( 
  
 keyset_handle 
 , 
  
 secret_key_access 
 . 
 TOKEN 
  
 ) 
  
 keyset_file 
 . 
 write 
 ( 
 serialized_keyset 
 ) 
  
 except 
  
 tink 
 . 
 TinkError 
  
 as 
  
 e 
 : 
  
 logging 
 . 
 exception 
 ( 
 ' 
 Error 
  
 writing 
  
 key 
 : 
  
 % 
 s 
 ' 
 , 
  
 e 
 ) 
  
 return 
  
 1 
  
 return 
  
 0 
  
 # 
  
 Use 
  
 the 
  
 input 
  
 keyset 
  
 to 
  
 encrypt 
 / 
 decrypt 
  
 data 
  
 # 
  
 Read 
  
 the 
  
 keyset 
  
 into 
  
 a 
  
 keyset_handle 
  
 with 
  
 open 
 ( 
 FLAGS 
 . 
 keyset_path 
 , 
  
 ' 
 rt 
 ' 
 ) 
  
 as 
  
 keyset_file 
 : 
  
 try 
 : 
  
 serialized_keyset 
  
 = 
  
 keyset_file 
 . 
 read 
 () 
  
 keyset_handle 
  
 = 
  
 tink 
 . 
 json_proto_keyset_format 
 . 
 parse 
 ( 
  
 serialized_keyset 
 , 
  
 secret_key_access 
 . 
 TOKEN 
  
 ) 
  
 except 
  
 tink 
 . 
 TinkError 
  
 as 
  
 e 
 : 
  
 logging 
 . 
 exception 
 ( 
 ' 
 Error 
  
 reading 
  
 key 
 : 
  
 % 
 s 
 ' 
 , 
  
 e 
 ) 
  
 return 
  
 1 
  
 # 
  
 Get 
  
 the 
  
 primitive 
  
 try 
 : 
  
 cipher 
  
 = 
  
 keyset_handle 
 . 
 primitive 
 ( 
 aead 
 . 
 Aead 
 ) 
  
 except 
  
 tink 
 . 
 TinkError 
  
 as 
  
 e 
 : 
  
 logging 
 . 
 error 
 ( 
 ' 
 Error 
  
 creating 
  
 primitive 
 : 
  
 % 
 s 
 ' 
 , 
  
 e 
 ) 
  
 return 
  
 1 
  
 with 
  
 open 
 ( 
 FLAGS 
 . 
 input_path 
 , 
  
 ' 
 rb 
 ' 
 ) 
  
 as 
  
 input_file 
 : 
  
 input_data 
  
 = 
  
 input_file 
 . 
 read 
 () 
  
 if 
  
 FLAGS 
 . 
 mode 
  
 == 
  
 ' 
 decrypt 
 ' 
 : 
  
 output_data 
  
 = 
  
 cipher 
 . 
 decrypt 
 ( 
 input_data 
 , 
  
 b 
 ' 
 envelope_example 
 ' 
 ) 
  
 elif 
  
 FLAGS 
 . 
 mode 
  
 == 
  
 ' 
 encrypt 
 ' 
 : 
  
 output_data 
  
 = 
  
 cipher 
 . 
 encrypt 
 ( 
 input_data 
 , 
  
 b 
 ' 
 envelope_example 
 ' 
 ) 
  
 else 
 : 
  
 logging 
 . 
 error 
 ( 
  
 ' 
 Error 
  
 mode 
  
 not 
  
 supported 
 . 
  
 Please 
  
 choose 
  
 "encrypt" 
  
 or 
  
 "decrypt" 
 . 
 ' 
 ) 
  
 return 
  
 1 
  
 with 
  
 open 
 ( 
 FLAGS 
 . 
 output_path 
 , 
  
 ' 
 wb 
 ' 
 ) 
  
 as 
  
 output_file 
 : 
  
 output_file 
 . 
 write 
 ( 
 output_data 
 ) 
 if 
  
 __name__ 
  
 == 
  
 ' 
 __main__ 
 ' 
 : 
  
 flags 
 . 
 mark_flags_as_required 
 ([ 
 ' 
 mode 
 ' 
 , 
  
 ' 
 keyset_path 
 ' 
 ]) 
  
 app 
 . 
 run 
 ( 
 main 
 ) 
  
Design a Mobile Site
View Site in Mobile | Classic
Share by: