@@ -19,7 +19,7 @@ class Examples {
1919 // Exmaple from readme
2020
2121 @Serializable
22- data class Payload constructor (
22+ data class Payload (
2323
2424 // only uses as many bytes as needed
2525 @PackedType(PackedIntegerType .DEFAULT )
@@ -91,38 +91,39 @@ class Examples {
9191
9292 @Test
9393 fun `encryption serialization` () {
94-
95- // Initialization
9694 Security .addProvider(BouncyCastleProvider ())
9795 val random = SecureRandom ()
9896
9997 // This key is stored permanently so we can read payloads after jvm restart
10098 val keyBytes = ByteArray (16 )
10199 random.nextBytes(keyBytes)
102100 val key = SecretKeySpec (keyBytes, " XTEA" )
103- val cipher = Cipher .getInstance(" XTEA/CTR/NoPadding" , " BC" )
104101
105- // Encrypt one payload
106- // we use 8 bytes as the initialization vector
102+ // Wrap XTEA/CTR as a PayloadTransform.
103+ // Each encode prepends a fresh 8-byte IV; decode reads it back.
104+ val xteaTransform = object : PayloadTransform {
105+ override fun encode (data : ByteArray ): ByteArray {
106+ val iv = ByteArray (8 ).also { random.nextBytes(it) }
107+ val cipher = Cipher .getInstance(" XTEA/CTR/NoPadding" , " BC" )
108+ cipher.init (Cipher .ENCRYPT_MODE , key, IvParameterSpec (iv))
109+ return iv + cipher.doFinal(data)
110+ }
111+
112+ override fun decode (data : ByteArray ): ByteArray {
113+ val iv = data.copyOfRange(0 , 8 )
114+ val cipher = Cipher .getInstance(" XTEA/CTR/NoPadding" , " BC" )
115+ cipher.init (Cipher .DECRYPT_MODE , key, IvParameterSpec (iv))
116+ return cipher.doFinal(data.copyOfRange(8 , data.size))
117+ }
118+ }
119+
120+ val secureFormat = EncodedFormat { transform = xteaTransform }
121+
107122 val payload = SensitiveData (random.nextLong())
108- val iv8 = ByteArray (8 )
109- random.nextBytes(iv8)
110- cipher.init (Cipher .ENCRYPT_MODE , key, IvParameterSpec (iv8))
111-
112- // This particular encryption adds 16-bytes in an initialization vector
113- // regardless of how big the payload is.
114- val encrypted =
115- iv8 + cipher.doFinal(PackedFormat .encodeToByteArray(payload))
116- val encoded = Base62 .encode(encrypted)
117- println (encoded)
123+ val token = secureFormat.encodeToString(SensitiveData .serializer(), payload)
124+ println (token)
118125
119- // This recovers the initial payload
120- val iv8received = encrypted.copyOfRange(0 , 8 )
121- val received = encrypted.copyOfRange(8 , encrypted.size)
122- cipher.init (Cipher .DECRYPT_MODE , key, IvParameterSpec (iv8received))
123- val decoded = Base62 .decode(encoded)
124- val decrypted = cipher.doFinal(received)
125- val result: SensitiveData = PackedFormat .decodeFromByteArray(decrypted)
126+ val result = secureFormat.decodeFromString(SensitiveData .serializer(), token)
126127 println (result)
127128
128129 assertEquals(payload, result)
0 commit comments