Linux-Fan

RSA Encryption/Decryption example

Jan 24th, 2012
680
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import java.security.*;
  2. import java.security.spec.*;
  3. import javax.crypto.*;
  4. import java.lang.*;
  5. import java.io.*;
  6. import java.math.*;
  7.  
  8. /*
  9.  * Greatest thanks for this example go to the address mentioned below:
  10.  */
  11.  
  12. // We're following http://www.javamex.com/tutorials/cryptography/asymmetric.shtml
  13. // to show how to do RSA enc/dec
  14. public class RSA {
  15.                    
  16.     private static final String algorithm = "RSA";
  17.                    
  18.     // 64 bytes
  19.     private static final String msgChecksum = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
  20.  
  21.     // Unlike in the original example, we want a TEXT file to actually SEE what it stores
  22.     private static void saveToFile(String fileName, BigInteger mod, BigInteger exp) throws IOException {
  23.         BufferedWriter out = new BufferedWriter(new FileWriter(fileName));
  24.         out.write(mod.toString());
  25.         out.newLine();
  26.         out.write(exp.toString());
  27.         out.newLine();
  28.         out.close();
  29.     }
  30.  
  31.     private static BigInteger[] readTwoNumbersFromFile(String fileName) throws IOException {
  32.         BigInteger[] ret = new BigInteger[2];
  33.         BufferedReader in = new BufferedReader(new FileReader(fileName));
  34.         ret[0] = new BigInteger(in.readLine());
  35.         ret[1] = new BigInteger(in.readLine());
  36.         in.close();
  37.         return ret;
  38.     }
  39.  
  40.     public static void main(String[] args) throws Exception {
  41.         if(args.length == 0) {
  42.             System.out.println("Usage: $0 1|2|3");
  43.             System.out.println("1 generate keys");
  44.             System.out.println("2 encrypt msg-checksum with endor key");
  45.             System.out.println("3 decrypt msg-checksum with gbz key");
  46.             System.out.println("4 AnDenNutzer proposal");
  47.             return;
  48.         }
  49.         switch(args[0].charAt(0)) {
  50.             case '1': {
  51.                 // Generate keys
  52.                 KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
  53.                 kpg.initialize(2048);
  54.                 KeyPair kp = kpg.genKeyPair();
  55.                 Key publicKey = kp.getPublic();
  56.                 Key privateKey = kp.getPrivate();
  57.                 // Store keys to file
  58.                 KeyFactory fact = KeyFactory.getInstance("RSA");
  59.                 RSAPublicKeySpec pub = fact.getKeySpec(kp.getPublic(), RSAPublicKeySpec.class);
  60.                 RSAPrivateKeySpec priv = fact.getKeySpec(kp.getPrivate(), RSAPrivateKeySpec.class);
  61.                 saveToFile("public.key", pub.getModulus(), pub.getPublicExponent());
  62.                 saveToFile("private.key", priv.getModulus(), priv.getPrivateExponent());
  63.                 // Actually, this is it!
  64.                 break;
  65.             }
  66.             case '2': {
  67.                 // Encrypt "msgChecksum" field with the "public.key" file (later this file shall NOT be distributed as it is THE important file... in the AnDenNutzer layout, endor actually plays the role of a client as he connects to gbz... or s04... that have a server (started with --client) running)
  68.                 // We'll later store our key files in setting-fields of our INI
  69.  
  70.                 // Read data from public.key
  71.                 BigInteger[] numbers = readTwoNumbersFromFile("public.key");
  72.                 RSAPublicKeySpec keySpec = new RSAPublicKeySpec(numbers[0], numbers[1]);
  73.                 KeyFactory fact = KeyFactory.getInstance("RSA");
  74.                 PublicKey pubKey = fact.generatePublic(keySpec);
  75.                 // Actual encryption
  76.                 Cipher cipher = Cipher.getInstance("RSA");
  77.                 cipher.init(Cipher.ENCRYPT_MODE, pubKey);
  78.                 byte[] cipherData = cipher.doFinal(msgChecksum.getBytes());
  79.                 // Write to file
  80.                 BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("msg_checksum_encrypted.bin"));
  81.                 out.write(cipherData);
  82.                 out.close();
  83.                 break;
  84.             }
  85.             case '3': {
  86.                 // Decrypt
  87.                 // modulus, exponent (reihenfolge!)
  88.                 BigInteger[] numbers = readTwoNumbersFromFile("private.key");
  89.                 RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(numbers[0], numbers[1]);
  90.                 KeyFactory fact = KeyFactory.getInstance("RSA");
  91.                 PrivateKey privateKey = fact.generatePrivate(keySpec);
  92.                 // Actual decryption
  93.                 Cipher cipher = Cipher.getInstance("RSA");
  94.                 cipher.init(Cipher.DECRYPT_MODE, privateKey);
  95.                 BufferedInputStream in = new BufferedInputStream(new FileInputStream("msg_checksum_encrypted.bin"));
  96.                 byte[] buffer = new byte[0x100];
  97.                 int len;
  98.                 while ((len = in.read(buffer)) > 0) {
  99.                     cipher.update(buffer, 0, len);
  100.                 }
  101.                 System.out.println(new String(cipher.doFinal()));
  102.                 break;
  103.             }
  104.             case '4': {
  105.                 // AnDenNutzer Variante
  106.                 // TODO PROBLEM BEI DER GANZEN SACHE: pwd-exponent auf dem Server ist zu leicht zu erraten (weil Standardwert) -- wir müssen auf dem Server sichere Werte als auf dem Client haben, aber der Client ist derjenige, der entschlüsseln muss.
  107.                 System.out.println("Generation in progress... Please wait a while...");
  108.                 KeyPairGenerator kpg = KeyPairGenerator.getInstance(algorithm);
  109.                 kpg.initialize(0x800);
  110.                 KeyPair kp = kpg.genKeyPair();
  111.                 KeyFactory fact = KeyFactory.getInstance(algorithm);
  112.                 RSAPublicKeySpec pub = fact.getKeySpec(kp.getPublic(), RSAPublicKeySpec.class);
  113.                 RSAPrivateKeySpec priv = fact.getKeySpec(kp.getPrivate(), RSAPrivateKeySpec.class);
  114.                 System.out.println("done.");
  115.                 System.out.println();
  116.                 System.out.println("Configuration for your server (that you invoke via --client=CLIENT MSG)");
  117.                 System.out.println("pwd-modulus=");
  118.                 printIndentedBigInteger(pub.getModulus());
  119.                 System.out.println("pwd-exponent=");
  120.                 printIndentedBigInteger(pub.getPublicExponent());
  121.                 System.out.println();
  122.                 System.out.println("Configuration for your client (that you invoke via --client)");
  123.                 System.out.println("pwd-modulus=");
  124.                 printIndentedBigInteger(priv.getModulus());
  125.                 System.out.println("pwd-exponent=");
  126.                 printIndentedBigInteger(priv.getPrivateExponent());
  127.                 System.out.println();
  128.                 System.out.println("Remember that you will need a different ini on server and client!");
  129.                 System.out.println("The numbers are quite large... you may want to redirect them into a file.");
  130.                 System.out.println("You will also have to remove the newlines and spaces between the numbers.");
  131.             }
  132.             default: {
  133.                 System.out.println("Use no param for help.");
  134.             }
  135.         }
  136.     }
  137.  
  138.     private static void printIndentedBigInteger(BigInteger integer) {
  139.         char[] chrData = integer.toString().toCharArray();
  140.         char[] buffer = new char[79];
  141.         int pos = 0;
  142.         for(int i = 0; i < chrData.length; i++) {
  143.             if(pos == 0) {
  144.                 pos = 8;
  145.                 for(int j = 0; j < 8; j++) {
  146.                     buffer[j] = ' ';
  147.                 }
  148.             }
  149.             buffer[pos++] = chrData[i];
  150.             if(pos > 78) {
  151.                 System.out.println(new String(buffer));
  152.                 pos = 0;
  153.             }
  154.         }
  155.         StringBuffer lastLine = new StringBuffer("");
  156.         for(int i = 0; i <= pos; i++) {
  157.             lastLine.append(buffer[i]);
  158.         }
  159.         System.out.println(lastLine);
  160.     }
  161.    
  162. }
RAW Paste Data