RSAの公開キーと秘密キーを生成し、
plain_message = "12345\nABCあいえお";の平文を公開鍵で暗号化しています。
これを、秘密キーで復号化して、表示しています。
import java.security.*; import java.security.interfaces.*;//RSAPublicKey, RSAPrivateKey import java.math.BigInteger; class RSA{ static final char[] B64 = { //変換に使うテーブル 64進(6bit分)を 16桁 4行で表現している 'A' ,'B' ,'C' ,'D' ,'E' ,'F' ,'G' ,'H' ,'I' ,'J' ,'K' ,'L' ,'M' ,'N' ,'O' ,'P',//00〜0Fの64進に対応する文字 'Q' ,'R' ,'S' ,'T' ,'U' ,'V' ,'W' ,'X' ,'Y' ,'Z' ,'a' ,'b' ,'c' ,'d' ,'e' ,'f',//10〜1Fの64進対応に対応する文字 'g' ,'h' ,'i' ,'j' ,'k' ,'l' ,'m' ,'n' ,'o' ,'p' ,'q' ,'r' ,'s' ,'t' ,'u' ,'v',//20〜2Fの64進対応に対応する文字 'w' ,'x' ,'y' ,'z' ,'0' ,'1' ,'2' ,'3' ,'4' ,'5' ,'6' ,'7' ,'8' ,'9' ,'+' ,'/' //30〜3Fの64進対応に対応する文字 }; //引数のbyte配列を、Base64の文字列に変換して返す。 public static String encode64(byte a[]) { if (a.length == 0) return ""; StringBuffer s = new StringBuffer();//変換した文字列記憶用 int cnt3 = 0; //3yteカウント用 long data = 0; //変換対象用:3byteを設定し、4文字で取り出す int idx = 0; do { //data に 3byte分を設定 data <<= 8; if (idx < a.length) { if (a[idx] >= 0) {//Javaは符号なしがないので、if文で処理を変える data += a[idx]; } else { data += 256 + a[idx]; //符号なしのコードに変換して加算 } } cnt3++; if (cnt3 == 3) {//3byteごとに変換 //dataを4個の64進に対応する文字に変換 int i = (int)(data / (64 * 64 * 64)); //System.out.println(data + "," + i + "," + 256 * 256 * 256); s.append(B64[i]);//1文字目 data = data % (64 * 64 * 64); i = (int)(data / (64 * 64)); s.append(B64[i]);//2文字目 data = data % (64 * 64); i = (int)(data / (64)); s.append(B64[i]);//3文字目 data = data % 64; s.append(B64[(int)data]);//4文字目 data = 0; //次の変換データの準備 cnt3 = 0; } idx++; } while (idx < a.length || cnt3 != 0); int len = s.length(); //文字列の長さ String rtnval = ""; if (a.length % 3 == 2) { return s.substring(0, len - 1) + "="; } else if (a.length % 3 == 1) { return s.substring(0, len - 2) + "=="; } else { return s.toString(); } } //Base64の文字列から、バイナリデータを求める。 public static byte[] decode64(String s) { int n = s.length() * 3 / 4; if (s.endsWith("==")) n -= 2; else if (s.endsWith("=")) n -= 1; byte[] bi = new byte[n]; int iset = 0; int len = s.length(); int data = 0; int icount = 0; int i; try { for (i = 0; i < len; i++) { //文字を順番に処理する。 char c = s.charAt(i); data <<= 6;// 6ビットシフト icount++; if (c != '=') { //Base64の文字から、テーブル内のインデックスを求める。 if (c >= 'A' && c <= 'Z') { data |= c - 'A'; } else if (c >= 'a' && c <= 'z') { data |= c - 'a' + 0x1a; } else if (c >= '0' && c <= '9') { data |= c - '0' + 0x34; } else if (c == '+') { data |= 0x3e; } else if (c == '/') { data |= 0x3f; } } if (icount == 4) { icount = 0; bi[iset++] = (byte)((data >> 16) & 0x00ff); bi[iset++] = (byte)((data >> 8) & 0x00ff); bi[iset++] = (byte)(data & 0x00ff); data = 0; } } } catch (ArrayIndexOutOfBoundsException e) { // =文字など無効なデータ分の設定は無視 //System.out.println( iset + "::::" + e.toString()); } return bi; } public static void main(String arg[]) throws Exception { // キーペアの生成 KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA"); SecureRandom random = SecureRandom.getInstance("SHA1PRNG"); generator.initialize(1024, random); KeyPair keyPair = generator.generateKeyPair(); // 秘密鍵・公開鍵の取得 RSAPublicKey publicKey = (RSAPublicKey)keyPair.getPublic(); RSAPrivateKey privateKey = (RSAPrivateKey)keyPair.getPrivate(); //平文 String plain_message = "12345\nABCあいえお"; System.out.print("平文『"); System.out.println(plain_message+"』"); //暗号化 plain_messageを暗号化して、enCodeNumに記憶 BigInteger exponentP = publicKey.getPublicExponent(); BigInteger modulusP = publicKey.getModulus(); BigInteger msg = new BigInteger( plain_message.getBytes() ); BigInteger enCodeNum = msg.modPow(exponentP, modulusP); System.out.print("\n公開鍵で暗号化したコード『"); System.out.println(encode64(enCodeNum.toByteArray())+"』"); //復号 enCodeNum を復号して、deCodeNumに記憶 BigInteger exponentS = privateKey.getPrivateExponent(); BigInteger modulusS = privateKey.getModulus(); BigInteger deCodeNum = enCodeNum.modPow(exponentS, modulusS); System.out.print("\n秘密鍵で復号したコード『"); System.out.println(new String(deCodeNum.toByteArray()) + "』"); } }