· 7 years ago · Nov 09, 2018, 08:44 AM
1import java.nio.ByteBuffer
2import java.security.SecureRandom
3import java.util.*
4import javax.crypto.Cipher
5import javax.crypto.spec.GCMParameterSpec
6import javax.crypto.spec.SecretKeySpec
7
8fun main(args: Array<String>) {
9
10 val secureRandom = SecureRandom()
11 val key = ByteArray(16) //DONT REUSE THIS SHIT, NIGGA
12 val secretKey = SecretKeySpec(key, "AES")
13 val initializationVector = ByteArray(12) //DONT REUSE THIS SHIT, ANOTHER NIGGA
14 val cipher = Cipher.getInstance("AES/GCM/NoPadding")
15 val parameterSpec = GCMParameterSpec(128, initializationVector)
16
17 fun printMe(key: ByteArray, tag: String) {
18 print("$tag: [")
19 for (i in 0 until key.size step 1) {
20 print(key[i])
21 if (i < key.size - 1) {
22 print(", ")
23 }
24 }
25 println("]")
26 }
27
28 fun dontReuseNigga() {
29 secureRandom.nextBytes(key)
30 secureRandom.nextBytes(initializationVector)
31 }
32
33 fun decrypt(cipherMessage: ByteArray) {
34 val byteBuffer = ByteBuffer.wrap(cipherMessage)
35 val ivLength = byteBuffer.int
36 if (ivLength < 12 || ivLength >= 16) { // check input parameter
37 throw IllegalArgumentException("invalid iv length")
38 }
39 val initializationVector = ByteArray(ivLength)
40 byteBuffer.get(initializationVector)
41 val cipherText = ByteArray(byteBuffer.remaining())
42 byteBuffer.get(cipherText)
43
44 cipher.init(Cipher.DECRYPT_MODE, secretKey, parameterSpec)
45 val plaintext = cipher.doFinal(cipherText)
46
47 println("[DECRYPTION RESULTS]")
48 println("Ciphertext: (Base64-encoded): " + Base64.getEncoder().encodeToString(cipherMessage))
49 println("Plaintext: " + String(plaintext))
50 }
51
52 fun decrypt(cipherText: String) {
53 decrypt(Base64.getDecoder().decode(cipherText))
54 }
55
56 fun encrypt(plainText: String) {
57 dontReuseNigga() //always initialize before every operation to generate a random seed
58 cipher.init(Cipher.ENCRYPT_MODE, secretKey, parameterSpec)
59 val cipherText = cipher.doFinal(plainText.toByteArray())
60
61 val byteBuffer = ByteBuffer.allocate(4 + initializationVector.size + cipherText.size)
62 byteBuffer.putInt(initializationVector.size)
63 byteBuffer.put(initializationVector)
64 byteBuffer.put(cipherText)
65 val cipherMessage = byteBuffer.array()
66
67 val base64Enc = Base64.getEncoder().encodeToString(cipherMessage)
68
69 //THIS IS ANTIHACKING MEASURES
70 //Clean the key array to remove traces of keys used in the encryption
71 //Do not depend on the GC to do this (its unpredictable when that nigga's gonna go to work)
72 printMe(key, "before")
73 Arrays.fill(key, 0)
74 printMe(key, "after")
75
76 println("[ENCRYPTION RESULTS]")
77 println("Plaintext: $plainText")
78 println("Ciphertext (Base64-encoded): $base64Enc")
79
80 //we saving the base64 encoded ciphertext so i made it possible to feed out decryptor
81 //with String or ByteArray parameters
82 decrypt(base64Enc)
83 decrypt(cipherMessage)
84 }
85
86 encrypt("This is a plaintext")
87
88}