Skip to content

Commit cdbb0eb

Browse files
committed
add java-crypto
1 parent 56c1954 commit cdbb0eb

File tree

8 files changed

+609
-0
lines changed

8 files changed

+609
-0
lines changed

java-crypto/pom.xml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
3+
<project xmlns="http://maven.apache.org/POM/4.0.0"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
6+
http://maven.apache.org/xsd/maven-4.0.0.xsd">
7+
<modelVersion>4.0.0</modelVersion>
8+
<groupId>com.mkyong</groupId>
9+
<artifactId>crypto</artifactId>
10+
<version>1.0</version>
11+
12+
<name>java-crypto</name>
13+
<url>https://mkyong.com</url>
14+
15+
<properties>
16+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
17+
<maven.compiler.source>11</maven.compiler.source>
18+
<maven.compiler.target>11</maven.compiler.target>
19+
<java.version>11</java.version>
20+
<junit.version>5.4.0</junit.version>
21+
</properties>
22+
23+
<dependencies>
24+
25+
<dependency>
26+
<groupId>org.junit.jupiter</groupId>
27+
<artifactId>junit-jupiter-params</artifactId>
28+
<version>${junit.version}</version>
29+
<scope>test</scope>
30+
</dependency>
31+
32+
<dependency>
33+
<groupId>commons-codec</groupId>
34+
<artifactId>commons-codec</artifactId>
35+
<version>1.14</version>
36+
</dependency>
37+
38+
</dependencies>
39+
40+
<build>
41+
<finalName>java11</finalName>
42+
<plugins>
43+
<plugin>
44+
<groupId>org.apache.maven.plugins</groupId>
45+
<artifactId>maven-compiler-plugin</artifactId>
46+
<version>3.8.0</version>
47+
<configuration>
48+
<source>${java.version}</source>
49+
<target>${java.version}</target>
50+
</configuration>
51+
</plugin>
52+
</plugins>
53+
</build>
54+
</project>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.mkyong;
2+
3+
public class HelloApp {
4+
5+
public static void main(String[] args) {
6+
System.out.println("Hello Java Crypto!");
7+
}
8+
9+
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
package com.mkyong.crypto.encryptor;
2+
3+
import com.mkyong.crypto.utils.CryptoUtils;
4+
5+
import javax.crypto.Cipher;
6+
import javax.crypto.SecretKey;
7+
import javax.crypto.spec.IvParameterSpec;
8+
import java.nio.ByteBuffer;
9+
import java.nio.charset.Charset;
10+
import java.nio.charset.StandardCharsets;
11+
12+
/**
13+
* AES-CBC inputs - 16 bytes IV, need the same IV and secret keys for encryption and decryption.
14+
* <p>
15+
* The output consist of iv, encrypted content and auth tag in the following format:
16+
* output = byte[] {i i i c c c c c c ...}
17+
* <p>
18+
* i = IV bytes
19+
* c = content bytes (encrypted content)
20+
*/
21+
public class EncryptorAesCbc {
22+
23+
// AES-CBC, IvParameterSpec, 16 bytes IV
24+
private static final String ENCRYPT_ALGO = "AES/CBC/PKCS5Padding";
25+
private static final int IV_LENGTH_BYTE = 16;
26+
private static final int AES_KEY_BIT = 256;
27+
28+
private static final Charset UTF_8 = StandardCharsets.UTF_8;
29+
30+
// AES-CBC needs IvParameterSpec
31+
public static byte[] encrypt(byte[] pText, SecretKey secret, byte[] iv) throws Exception {
32+
33+
Cipher cipher = Cipher.getInstance(ENCRYPT_ALGO);
34+
cipher.init(Cipher.ENCRYPT_MODE, secret, new IvParameterSpec(iv));
35+
byte[] encryptedText = cipher.doFinal(pText);
36+
return encryptedText;
37+
38+
}
39+
40+
// prefix IV length + IV bytes to cipher text
41+
public static byte[] encryptWithPrefixIV(byte[] pText, SecretKey secret, byte[] iv) throws Exception {
42+
43+
byte[] cipherText = encrypt(pText, secret, iv);
44+
45+
byte[] cipherTextWithIv = ByteBuffer.allocate(iv.length + cipherText.length)
46+
.put(iv)
47+
.put(cipherText)
48+
.array();
49+
return cipherTextWithIv;
50+
51+
}
52+
53+
public static String decrypt(byte[] cText, SecretKey secret, byte[] iv) throws Exception {
54+
55+
Cipher cipher = Cipher.getInstance(ENCRYPT_ALGO);
56+
cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(iv));
57+
byte[] plainText = cipher.doFinal(cText);
58+
return new String(plainText, UTF_8);
59+
60+
}
61+
62+
public static String decryptWithPrefixIV(byte[] cText, SecretKey secret) throws Exception {
63+
64+
ByteBuffer bb = ByteBuffer.wrap(cText);
65+
66+
byte[] iv = new byte[IV_LENGTH_BYTE];
67+
bb.get(iv);
68+
//bb.get(iv, 0, iv.length);
69+
70+
byte[] cipherText = new byte[bb.remaining()];
71+
bb.get(cipherText);
72+
73+
String plainText = decrypt(cipherText, secret, iv);
74+
return plainText;
75+
76+
}
77+
78+
public static void main(String[] args) throws Exception {
79+
80+
String OUTPUT_FORMAT = "%-30s:%s";
81+
82+
String pText = "Hello World AES-CBC";
83+
84+
// encrypt and decrypt need the same key.
85+
// get AES 256 bits (32 bytes) key
86+
SecretKey secretKey = CryptoUtils.getAESKey(AES_KEY_BIT);
87+
88+
// encrypt and decrypt need the same IV.
89+
// AES-CBC needs IV 128-bit (16 bytes)
90+
byte[] iv = CryptoUtils.getRandomNonce(IV_LENGTH_BYTE);
91+
92+
byte[] encryptedText = EncryptorAesCbc.encryptWithPrefixIV(pText.getBytes(UTF_8), secretKey, iv);
93+
94+
System.out.println("\n------ AES CBC Encryption ------");
95+
System.out.println(String.format(OUTPUT_FORMAT, "Input (plain text)", pText));
96+
System.out.println(String.format(OUTPUT_FORMAT, "Key (hex)", CryptoUtils.hex(secretKey.getEncoded())));
97+
System.out.println(String.format(OUTPUT_FORMAT, "IV (hex)", CryptoUtils.hex(iv)));
98+
System.out.println(String.format(OUTPUT_FORMAT, "Encrypted (hex) ", CryptoUtils.hex(encryptedText)));
99+
System.out.println(String.format(OUTPUT_FORMAT, "Encrypted (hex) (block = 16)", CryptoUtils.hexWithBlockSize(encryptedText, 16)));
100+
101+
System.out.println("\n------ AES CBC Decryption ------");
102+
System.out.println(String.format(OUTPUT_FORMAT, "Input (hex)", CryptoUtils.hex(encryptedText)));
103+
System.out.println(String.format(OUTPUT_FORMAT, "Input (hex) (block = 16)", CryptoUtils.hexWithBlockSize(encryptedText, 16)));
104+
System.out.println(String.format(OUTPUT_FORMAT, "Key (hex)", CryptoUtils.hex(secretKey.getEncoded())));
105+
106+
String decryptedText = EncryptorAesCbc.decryptWithPrefixIV(encryptedText, secretKey);
107+
108+
System.out.println(String.format(OUTPUT_FORMAT, "Decrypted (plain text)", decryptedText));
109+
110+
}
111+
112+
}
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
package com.mkyong.crypto.encryptor;
2+
3+
import com.mkyong.crypto.utils.CryptoUtils;
4+
5+
import javax.crypto.Cipher;
6+
import javax.crypto.SecretKey;
7+
import javax.crypto.spec.GCMParameterSpec;
8+
import java.nio.ByteBuffer;
9+
import java.nio.charset.Charset;
10+
import java.nio.charset.StandardCharsets;
11+
12+
/**
13+
* AES-GCM inputs - 12 bytes IV, need the same IV and secret keys for encryption and decryption.
14+
* <p>
15+
* The output consist of iv, encrypted content and auth tag in the following format:
16+
* output = byte[] {i i i c c c c c c ...}
17+
* <p>
18+
* i = IV bytes
19+
* c = content bytes (encrypted content, auth tag)
20+
*/
21+
public class EncryptorAesGcm {
22+
23+
// AES-CBC
24+
// IvParameterSpec, 16 bytes IV
25+
// private static final String ENCRYPT_ALGO = "AES/CBC/PKCS5Padding";
26+
27+
private static final String ENCRYPT_ALGO = "AES/GCM/NoPadding";
28+
private static final int TAG_LENGTH_BIT = 128;
29+
private static final int IV_LENGTH_BYTE = 12;
30+
private static final int AES_KEY_BIT = 256;
31+
private static final Charset UTF_8 = StandardCharsets.UTF_8;
32+
33+
// AES-GCM needs GCMParameterSpec
34+
public static byte[] encrypt(byte[] pText, SecretKey secret, byte[] iv) throws Exception {
35+
36+
Cipher cipher = Cipher.getInstance(ENCRYPT_ALGO);
37+
cipher.init(Cipher.ENCRYPT_MODE, secret, new GCMParameterSpec(TAG_LENGTH_BIT, iv));
38+
byte[] encryptedText = cipher.doFinal(pText);
39+
return encryptedText;
40+
41+
}
42+
43+
// prefix IV length + IV bytes to cipher text
44+
public static byte[] encryptWithPrefixIV(byte[] pText, SecretKey secret, byte[] iv) throws Exception {
45+
46+
byte[] cipherText = encrypt(pText, secret, iv);
47+
48+
byte[] cipherTextWithIv = ByteBuffer.allocate(iv.length + cipherText.length)
49+
.put(iv)
50+
.put(cipherText)
51+
.array();
52+
return cipherTextWithIv;
53+
54+
}
55+
56+
public static String decrypt(byte[] cText, SecretKey secret, byte[] iv) throws Exception {
57+
58+
Cipher cipher = Cipher.getInstance(ENCRYPT_ALGO);
59+
cipher.init(Cipher.DECRYPT_MODE, secret, new GCMParameterSpec(TAG_LENGTH_BIT, iv));
60+
byte[] plainText = cipher.doFinal(cText);
61+
return new String(plainText, UTF_8);
62+
63+
}
64+
65+
public static String decryptWithPrefixIV(byte[] cText, SecretKey secret) throws Exception {
66+
67+
ByteBuffer bb = ByteBuffer.wrap(cText);
68+
69+
byte[] iv = new byte[IV_LENGTH_BYTE];
70+
bb.get(iv);
71+
//bb.get(iv, 0, iv.length);
72+
73+
byte[] cipherText = new byte[bb.remaining()];
74+
bb.get(cipherText);
75+
76+
String plainText = decrypt(cipherText, secret, iv);
77+
return plainText;
78+
79+
}
80+
81+
public static void main(String[] args) throws Exception {
82+
83+
String OUTPUT_FORMAT = "%-30s:%s";
84+
85+
String pText = "Hello World AES-GCM, Welcome to Cryptography!";
86+
87+
// encrypt and decrypt need the same key.
88+
// get AES 256 bits (32 bytes) key
89+
SecretKey secretKey = CryptoUtils.getAESKey(AES_KEY_BIT);
90+
91+
// encrypt and decrypt need the same IV.
92+
// AES-GCM needs IV 96-bit (12 bytes)
93+
byte[] iv = CryptoUtils.getRandomNonce(IV_LENGTH_BYTE);
94+
95+
byte[] encryptedText = EncryptorAesGcm.encryptWithPrefixIV(pText.getBytes(UTF_8), secretKey, iv);
96+
97+
System.out.println("\n------ AES GCM Encryption ------");
98+
System.out.println(String.format(OUTPUT_FORMAT, "Input (plain text)", pText));
99+
System.out.println(String.format(OUTPUT_FORMAT, "Key (hex)", CryptoUtils.hex(secretKey.getEncoded())));
100+
System.out.println(String.format(OUTPUT_FORMAT, "IV (hex)", CryptoUtils.hex(iv)));
101+
System.out.println(String.format(OUTPUT_FORMAT, "Encrypted (hex) ", CryptoUtils.hex(encryptedText)));
102+
System.out.println(String.format(OUTPUT_FORMAT, "Encrypted (hex) (block = 16)", CryptoUtils.hexWithBlockSize(encryptedText, 16)));
103+
104+
System.out.println("\n------ AES GCM Decryption ------");
105+
System.out.println(String.format(OUTPUT_FORMAT, "Input (hex)", CryptoUtils.hex(encryptedText)));
106+
System.out.println(String.format(OUTPUT_FORMAT, "Input (hex) (block = 16)", CryptoUtils.hexWithBlockSize(encryptedText, 16)));
107+
System.out.println(String.format(OUTPUT_FORMAT, "Key (hex)", CryptoUtils.hex(secretKey.getEncoded())));
108+
109+
String decryptedText = EncryptorAesGcm.decryptWithPrefixIV(encryptedText, secretKey);
110+
111+
System.out.println(String.format(OUTPUT_FORMAT, "Decrypted (plain text)", decryptedText));
112+
113+
}
114+
115+
}

0 commit comments

Comments
 (0)