Java+RSA公開鍵暗号化 -> Ruby+RSA秘密鍵復号
JavaからRSA公開鍵で暗号化したデータをRubyからRSA秘密鍵で復号するサンプル。
鍵の保存
require 'openssl' OpenSSL::Random.seed(File.read("/dev/random", 16)) rsa = OpenSSL::PKey::RSA.generate(2048) # 秘密鍵を保存 File.open("private_key.pem", "w") do |f| f.write(rsa.export) end # 公開鍵を保存 public_key = rsa.public_key File.open("public_key.pem", "w") do |f| f.write(public_key.export) end
Java+RSA公開鍵暗号化
package com.example; import java.io.IOException; import java.io.InputStream; import java.security.GeneralSecurityException; import java.security.KeyFactory; import java.security.PublicKey; import java.security.spec.X509EncodedKeySpec; import javax.crypto.Cipher; import org.apache.commons.codec.binary.Base64; import org.apache.commons.io.IOUtils; public class RSAPublicKeyExample { public static void main(String[] args) throws Exception { RSAPublicKeyExample example = new RSAPublicKeyExample(); String encrypted = example.encrypt("test"); System.out.println(encrypted); } public String encrypt(String data) throws IOException, GeneralSecurityException { // ファイルから公開鍵を読み込む PublicKey key = readPublicKeyPem(this.getClass().getResourceAsStream("/public.pem")); Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.ENCRYPT_MODE, key); // 暗号化+Base64 byte[] encrypted = cipher.doFinal(data.getBytes()); return Base64.encodeBase64String(encrypted); } private PublicKey readPublicKeyPem(InputStream stream) throws IOException, GeneralSecurityException { // PEMのヘッダとフッタを削除 String pem = IOUtils.toString(stream) .replaceAll("(-+BEGIN PUBLIC KEY-+\\r?\\n|-+END PUBLIC KEY-+\\r?\\n?)", ""); byte[] decoded = Base64.decodeBase64(pem); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decoded); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PublicKey key = keyFactory.generatePublic(keySpec); return key; } }
Ruby+RSA秘密鍵復号
require 'openssl' require 'base64' # ファイルから秘密鍵を読み込む rsa = OpenSSL::PKey::RSA.new(open('private_key.pem')) # 復号 puts rsa.private_decrypt(Base64.decode64('{Javaで暗号化+Base64した文字列}')) # => test