1 package cn.home1.oss.lib.common.crypto;
2
3 import static cn.home1.oss.lib.common.crypto.CryptoConstants.COLON;
4 import static cn.home1.oss.lib.common.crypto.RsaKey.KEY_FORMAT_PKCS1;
5 import static cn.home1.oss.lib.common.crypto.RsaKey.KEY_FORMAT_PKCS8;
6 import static cn.home1.oss.lib.common.crypto.RsaKey.KEY_FORMAT_PKCS8_X509;
7 import static cn.home1.oss.lib.common.crypto.RsaKey.KEY_FORMAT_X509;
8 import static cn.home1.oss.lib.common.crypto.RsaKey.KEY_TYPE_PAIR;
9 import static cn.home1.oss.lib.common.crypto.RsaKey.KEY_TYPE_PRIVATE;
10 import static cn.home1.oss.lib.common.crypto.RsaKey.KEY_TYPE_PUBLIC;
11 import static cn.home1.oss.lib.common.crypto.RsaKey.extractPrivateKey;
12 import static cn.home1.oss.lib.common.crypto.RsaKey.extractPublicKey;
13 import static cn.home1.oss.lib.common.crypto.RsaKey.keySize;
14 import static cn.home1.oss.lib.common.crypto.RsaKey.keySpec;
15 import static cn.home1.oss.lib.common.crypto.RsaKeyGenerator.pem;
16 import static java.nio.charset.StandardCharsets.US_ASCII;
17 import static lombok.AccessLevel.PRIVATE;
18 import static org.apache.commons.io.FileUtils.writeStringToFile;
19
20 import cn.home1.oss.lib.common.CodecUtils;
21
22 import lombok.NoArgsConstructor;
23 import lombok.SneakyThrows;
24
25 import java.io.File;
26
27
28
29
30 @NoArgsConstructor(access = PRIVATE)
31 public abstract class RsaKeys {
32
33 public static String generateRsaKey(final int keySize) {
34 final String spec = RsaKey.keySpec(KEY_FORMAT_PKCS8_X509, keySize, KEY_TYPE_PAIR);
35 final RsaKeyGenerator rsaKeyGenerator = new RsaKeyGenerator(spec);
36 final KeyExpression pairPkcs8X509 = rsaKeyGenerator.generateKey();
37 final KeyExpression pairPkcs1 = RsaKeyGenerator.convertPairFromPkcs8X509ToPkcs1(pairPkcs8X509);
38
39 final StringBuilder result = new StringBuilder();
40
41 System.err.println("privateKey PKCS8: " + writePemFile(pairPkcs8X509, KEY_FORMAT_PKCS8, KEY_TYPE_PRIVATE));
42 final String privateKeyPkcs1PemFile = writePemFile(pairPkcs1, KEY_FORMAT_PKCS1, KEY_TYPE_PRIVATE);
43 System.err.println("privateKey PKCS1: " + privateKeyPkcs1PemFile);
44 System.err.println("Check with command line OpenSSL that the key format is as expected:");
45 System.err.println("openssl rsa -in " + privateKeyPkcs1PemFile + " -noout -text");
46
47 System.err.println("publicKey x509: " + writePemFile(pairPkcs8X509, KEY_FORMAT_X509, KEY_TYPE_PUBLIC));
48 System.err.println("publicKey PKCS1: " + writePemFile(pairPkcs1, KEY_FORMAT_PKCS1, KEY_TYPE_PUBLIC));
49
50 return result
51 .append(pairPkcs8X509.toString()).append("\n")
52 .append(pairPkcs1.toString()).append("\n")
53 .append(keySpec(KEY_TYPE_PRIVATE, keySize, KEY_FORMAT_PKCS1)).append(COLON)
54 .append(extractPrivateKey(pairPkcs1)).append("\n")
55 .append(keySpec(KEY_TYPE_PRIVATE, keySize, KEY_FORMAT_PKCS8)).append(COLON)
56 .append(extractPrivateKey(pairPkcs8X509)).append("\n")
57 .append(keySpec(KEY_TYPE_PUBLIC, keySize, KEY_FORMAT_PKCS1)).append(COLON)
58 .append(extractPublicKey(pairPkcs1)).append("\n")
59 .append(keySpec(KEY_TYPE_PUBLIC, keySize, KEY_FORMAT_X509)).append(COLON)
60 .append(extractPublicKey(pairPkcs8X509))
61 .toString();
62 }
63
64 public static File keyFile(final String keyFormat, final int keySize, final String keyType) {
65
66 final String targetDirectory = System.getProperty("user.dir", "/tmp");
67 return new File(targetDirectory + "/" + keySpec(keyType, keySize, keyFormat) + ".pem");
68 }
69
70 @SneakyThrows
71 public static String writePemFile(final KeyExpression pair, final String keyFormat, final String keyType) {
72 final int keySize = keySize(pair.getSpec());
73 final File pemFile = keyFile(keyFormat, keySize, keyType);
74 final byte[] bytes = CodecUtils.decodeBase64(KEY_TYPE_PRIVATE.equals(keyType) ?
75 extractPrivateKey(pair) : extractPublicKey(pair));
76 writeStringToFile(pemFile, pem(bytes, keyFormat, keyType), US_ASCII);
77 return pemFile.getPath();
78 }
79 }