JavaSE RSA暗号 の Java8 版。RSA暗号の基礎についてはそちらを参考にすること
#!/bin/bash # (1) Create the secret key openssl genrsa -out secret.key 2048 # (2) Create a public key # We can create public keys from a secret key easily. openssl rsa -pubout < secret.key > public.key # (3) Convert the secret key to PKSC8 format that Java can read. openssl pkcs8 -in secret.key -out secret.key.pkcs8 -topk8 -nocrypt
-----BEGIN PRIVATE KEY----- MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCbEv3idv0kS1x4 Bcb+Mgt5iMwNh7mo6fWUGbyehXjXZaFtEIqaElQLqq8i7JAEexP2wF296GHLWlX1 ZP14D+fJlBVjacxefl5oIxy/mp0I6kSoskKZhpImxmzT5p8w90++S5EM0Q5/4n86 E2wlW4J9lVQShJQ4PKxqZzoVXwys/IgW94Vc1emjgDbM3DhbRiZrhhLeD8kAGluq +ZOM57OtLHVkMTJFBNLWOd7XhECyJx0/LRIq0tJcjHPlk8eOH/dai85g/t9X3wBB hC4RmSaYmGOLy0soUzvRUpUWd7F5quUbIvHcpc5GnDycP7STnjiQ/gmnTr/B3mTA QdxvR8gRAgMBAAECggEAHhiGe2AaauPRU13Tq9usjG63I10W9ChLx+1ixOUkebE4 rgEK1TH/a7A5gy6kGKqGSlo1Fzk1WZDzo8dwxc9Yba+2ou+SgThHPDCsUKdCGMvW fWLzN/Z9ANd7oXhdptQofscNpI4iIUGk7XF9iJaE8bh8c4eVeICV+aSFCkbDIAMp U6D7DIRit0U9PJS7lH9whG10vzW3ipZR7bhyTINDJebaGQAXJfdtOnFd10veGgPy NCAJYkhf/p+HGIFKTVxRLYH5vZNZVbFrDz7bTvz9RvT+J80Bi1Msyh/UkFgn7+ed o/ji5brIVStAFpXEwfwcEC819GT9dRIyap4vks6GjQKBgQDH7W7KNqtSHDG6SRhM zlFBm+2qgs2+utYcQ6dUtL1zaX5WrRp+MvLWCQ7E1DZYxTdYZ4Tu6mPvBNF4/6cY ti1TuVVVBKIoIOz7vQ85krooqSNS+gywL7gEzxf+C74cS4ZcAxO94RKvFGx59fLr p85puG9WXnJIyFvK/Rq4ztxxswKBgQDGkSTD0F/x4yDoZqlovPrpXMTtBc7WCK+d 5pllNT4p8JgpOYKflGx0w1/eryhcQ5qlV3XzLl0XAnsANgs4VzNgyk9OZdxI5Usq r4f22oZtGZQUJ/jTrvIfX4bhBs5Em/JOiBkMR3YY0Q9uPR4Af220y5HbhvSKQWRW 4f77MN8VKwKBgQCNUPLi1Em8vFkaB9i5UYx2B7WytMqhaoc1a0y3vxm6nnLC6ZC0 a2bii3x4/Fd938kDIAkCp4MDzDAUiwCdowffCj2a3q+QFdXtCvHcDC6x1vw1BrI5 R0GXhJq846f5cBkEqNgnexQt1Q3oF0Uh9Xcdm1R3hELb12Oq08UzpGSFqQKBgQCn 56m37qaCynVULyNHTq240NowNr4MnHGryoehXiE/o5N3IItE12PSZDbX/TLaucu1 zjwNswHCaDWMGybnsEzgppHjEBzygvlJkf4djfEnpf5iAN7WWNOiFcve0jtvJpMB NvI/QNoq5/TtWb7Z2ubwf0bJ49c6ZUsscJOE4nFw2wKBgDGlcFFZ+uueQvR48nJ9 L36/QcVuyPhKtDqQ6YWcBb8PlQjGbaVKOruW4Xjj0yc9i3SNJkzYXx7cR5vhYkui nUkLhwHWy9b6dtTKY0vGFlTfCvint+VxskGo9CsHMbqIFQUmNhUu+TSLd/RWjtfy KwdX/9Mzk+D2MG7Ytl4XARCN -----END PRIVATE KEY-----
-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmxL94nb9JEtceAXG/jIL eYjMDYe5qOn1lBm8noV412WhbRCKmhJUC6qvIuyQBHsT9sBdvehhy1pV9WT9eA/n yZQVY2nMXn5eaCMcv5qdCOpEqLJCmYaSJsZs0+afMPdPvkuRDNEOf+J/OhNsJVuC fZVUEoSUODysamc6FV8MrPyIFveFXNXpo4A2zNw4W0Yma4YS3g/JABpbqvmTjOez rSx1ZDEyRQTS1jne14RAsicdPy0SKtLSXIxz5ZPHjh/3WovOYP7fV98AQYQuEZkm mJhji8tLKFM70VKVFnexearlGyLx3KXORpw8nD+0k544kP4Jp06/wd5kwEHcb0fI EQIDAQAB -----END PUBLIC KEY-----
package com.mycompany.rsaexam; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.file.Files; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.PublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.Base64; import javax.crypto.Cipher; public class RSAUtil { public static String encryptLicense(File license) throws Exception { PrivateKey priKey = KeyFactory.getInstance("RSA") .generatePrivate(new PKCS8EncodedKeySpec(readKey("secret.key.pkcs8"))); Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, priKey); byte[] rawLicense = Files.readAllBytes(license.toPath()); byte[] encryptedLicense = cipher.doFinal(rawLicense); byte[] base64License = Base64.getMimeEncoder().encode(encryptedLicense); return new String(base64License); } public static String decryptLicense(File license) throws Exception { PublicKey pubKey = KeyFactory.getInstance("RSA") .generatePublic(new X509EncodedKeySpec(readKey("public.key"))); Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, pubKey); byte[] base64License = Files.readAllBytes(license.toPath()); byte[] encryptedLicense = Base64.getMimeDecoder().decode(base64License); byte[] rawLicense = cipher.doFinal(encryptedLicense); return new String(rawLicense); } private static byte[] readKey(final String fileName) throws Exception { ClassLoader loader = Thread.currentThread().getContextClassLoader(); InputStream keyStream = loader.getResourceAsStream(fileName); try ( BufferedReader br = new BufferedReader(new InputStreamReader(keyStream))) { String line; StringBuilder sb = new StringBuilder(); boolean isContents = false; while ((line = br.readLine()) != null) { if (line.matches("[-]+BEGIN[ A-Z]+[-]+")) { isContents = true; } else if (line.matches("[-]+END[ A-Z]+[-]+")) { break; } else if (isContents) { sb.append(line); } } return Base64.getDecoder().decode(sb.toString()); } catch (FileNotFoundException e) { throw new Exception("File not found.", e); } catch (IOException e) { throw new Exception("can't read the PEM file.", e); } } }
package com.mycompany.rsaexam.test; import com.mycompany.rsaexam.RSAUtil; import java.io.File; import java.io.FileOutputStream; import org.junit.Test; public class RSAUtilTest { public RSAUtilTest() { } @Test public void hello() throws Exception { String encrypted = RSAUtil.encryptLicense(new File("src/test/resources/License.txt")); System.out.println("***** ENCREPTYED *****"); System.out.println(encrypted); File tmpFile = File.createTempFile("tmp", ".txt"); tmpFile.deleteOnExit(); try (FileOutputStream fout = new FileOutputStream(tmpFile)) { fout.write(encrypted.getBytes()); } String decripted = RSAUtil.decryptLicense(tmpFile); System.out.println("***** DECRYPTED *****"); System.out.println(decripted); } }
# BEGIN-------cut here-------CUT HERE-------BEGIN # SUPER MORIO Bros license passcode file. LicenseNo: 12345 HostID: INTERNET=144.212.101.43 UserName: Ichiro Suzuki Expire: 2020-12-31 # END---------cut here-------CUT HERE-------END
------------------------------------------------------- T E S T S ------------------------------------------------------- Running com.mycompany.rsaexam.test.RSAUtilTest ***** ENCREPTYED ***** eADSGtqPW6On70iGxl6LB2BTVVnnPjsNCAxIyJtV87nKKJgJy3loyN9+KV+2sKDjTHjrSkGkHhDK Kqe5HC/4ECY6GQHVF9PSsjCER+4FvgKFAlfDuLtjiFJU6VHnOSv0a1OU3aqJY90KcKDlOJr+5M4w xiqbqFZjIBWHHEjLqhNNXRn512Kjd3cJKFInFdGlHsJNSLe3A3JwbI2F2+AvUNzrEvgWNimUzEkI J9cVTgYG3PVs9CsKvx+Ji9kYHhJgQzKjudMbJ7rfQwnfASvsYj2579fDvz2yHHAilFD06TQNU6mP uvftt/HaUR8O0tUXfOHubPhImGF0nuxj4fAtRQ== ***** DECRYPTED ***** # BEGIN-------cut here-------CUT HERE-------BEGIN # SUPER MORIO Bros license passcode file. LicenseNo: 12345 HostID: INTERNET=144.212.101.43 UserName: Ichiro Suzuki Expire: 2020-12-31 # END---------cut here-------CUT HERE-------END Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.257 sec Results : Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
共通鍵 ==公開鍵RSAで暗号化==> 暗号1 平文 ==共通鍵AESで暗号化==> 暗号2
暗号1 ==秘密鍵RSAで復号化===> 共通鍵AES 暗号2 ==共通鍵AESで復号化===> 平文