bouncycastle(5)Learn from others RSA

bouncycastle(5)Learn from others RSA

RSA
There are 2 keys in RSA, one is private, one is public. They can be used to encrypt/decrypt and signing.

A will generate private/public key pair. A shares the public key to B.
A will sign and encrypt the data, send the data to B.
B will use public key to validate the signing and decrypt the data.

B will use public key to encrypt the data.
A will use private key to decrypt the data.

The implementation class is as follow:
package com.sillycat.easycastle.encryption;
import javax.crypto.Cipher;
public class RSACoder extends Coder {
     public static final String KEY_ALGORITHM = "RSA";
     public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
     private static final String PUBLIC_KEY = "RSAPublicKey";
     private static final String PRIVATE_KEY = "RSAPrivateKey";
     /**
     * use private key to generate the signing data
     * @param data
     * @param privateKey
     * @return
     * @throws Exception
     */
     public static String sign(byte[] data, String privateKey) throws Exception {
          // decrypt the private key via base64
          byte[] keyBytes = decryptBASE64(privateKey);
          // construct PKCS8EncodedKeySpec object
          PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
          // KEY_ALGORITHM RSA
          KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
          // convert to key object from private key string
          PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);

          // signature
          Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
          signature.initSign(priKey);
          signature.update(data);

          return encryptBASE64(signature.sign());
     }

     /**
     * validate the signature
     * @param data
     * @param publicKey
     * @param sign
     *
     * @return true false
     * @throws Exception
     */
     public static boolean verify(byte[] data, String publicKey, String sign)
               throws Exception {
          // decrypt the public key via base64
          byte[] keyBytes = decryptBASE64(publicKey);
          // construct X509EncodedKeySpec object
          X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
          // KEY_ALGORITHM
          KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
          // convert to public key from public key string
          PublicKey pubKey = keyFactory.generatePublic(keySpec);

          Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
          signature.initVerify(pubKey);
          signature.update(data);

          // validate the signature
          return signature.verify(decryptBASE64(sign));
     }

     /**
     * decryption via private key
     *
     * @param data
     * @param key
     * @return
     * @throws Exception
     */
     public static byte[] decryptByPrivateKey(byte[] data, String privateKeyString)
               throws Exception {
          // decrypt key from string
          byte[] keyBytes = decryptBASE64(privateKeyString);

          // get the private key
          PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
          KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
          Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);

          // decrypt the data via private key
          Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
          cipher.init(Cipher.DECRYPT_MODE, privateKey);

          return cipher.doFinal(data);
     }

     /**
     * decrypt via public key
     *
     * @param data
     * @param key
     * @return
     * @throws Exception
     */
     public static byte[] decryptByPublicKey(byte[] data, String publicKeyString)
               throws Exception {
          // decrypt the key string
          byte[] keyBytes = decryptBASE64(publicKeyString);

          // convert the key object to get the public key
          X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
          KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
          Key publicKey = keyFactory.generatePublic(x509KeySpec);

          // decrypt the data with public key
          Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
          cipher.init(Cipher.DECRYPT_MODE, publicKey);

          return cipher.doFinal(data);
     }

     /**
     * encrypt via public key
     *
     * @param data
     * @param key
     * @return
     * @throws Exception
     */
     public static byte[] encryptByPublicKey(byte[] data, String publicKeyString)
               throws Exception {
          // decrypt the public key
          byte[] keyBytes = decryptBASE64(publicKeyString);

          // convert to public key object
          X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
          KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
          Key publicKey = keyFactory.generatePublic(x509KeySpec);

          // encrypt the data via public key
          Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
          cipher.init(Cipher.ENCRYPT_MODE, publicKey);

          return cipher.doFinal(data);
     }

     /**
     * encrypt the data via private key
     *
     * @param data
     * @param key
     * @return
     * @throws Exception
     */
     public static byte[] encryptByPrivateKey(byte[] data, String privateKeyString)
               throws Exception {
          // decrypt the key from string
          byte[] keyBytes = decryptBASE64(privateKeyString);

          // convert to private key object
          PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
          KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
          Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);

          // encrypt the data
          Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
          cipher.init(Cipher.ENCRYPT_MODE, privateKey);

          return cipher.doFinal(data);
     }

     /**
     * get the private key
     *
     * @param keyMap
     * @return
     * @throws Exception
     */
     public static String getPrivateKey(Map<String, Object> keyMap)
               throws Exception {
          Key key = (Key) keyMap.get(PRIVATE_KEY);
          return encryptBASE64(key.getEncoded());
     }

     /**
     * get public key
     *
     * @param keyMap
     * @return
     * @throws Exception
     */
     public static String getPublicKey(Map<String, Object> keyMap)
               throws Exception {
          Key key = (Key) keyMap.get(PUBLIC_KEY);
          return encryptBASE64(key.getEncoded());
     }

     /**
     * initiate the key pair
     * @return
     * @throws Exception
     */
     public static Map<String, Object> initKey() throws Exception {
          KeyPairGenerator keyPairGen = KeyPairGenerator
                    .getInstance(KEY_ALGORITHM);
          keyPairGen.initialize(1024);
          KeyPair keyPair = keyPairGen.generateKeyPair();
          // public key
          RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
          // private key
          RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
          Map<String, Object> keyMap = new HashMap<String, Object>(2);
          keyMap.put(PUBLIC_KEY, publicKey);
          keyMap.put(PRIVATE_KEY, privateKey);
          return keyMap;
     }
}

And the test class is as follow:
package com.sillycat.easycastle.encryption;
import static org.junit.Assert.*;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;

public class RSACoderTest {

     private String publicKey;
     private String privateKey;

     @Before
     public void setUp() throws Exception {
          Map<String, Object> keyMap = RSACoder.initKey();
          publicKey = RSACoder.getPublicKey(keyMap);
          privateKey = RSACoder.getPrivateKey(keyMap);
          System.out.println("public key : \n\r" + publicKey);
          System.out.println("private key: \n\r" + privateKey);
     }

     @Test
     public void test() throws Exception {
          System.out.println("public key encryption——private key decryption");
          String inputStr = "hello, sillycat.";
          byte[] data = inputStr.getBytes();
          byte[] encodedData = RSACoder.encryptByPublicKey(data, publicKey);

          byte[] decodedData = RSACoder.decryptByPrivateKey(encodedData,
                    privateKey);

          String outputStr = new String(decodedData);
          System.out.println("original: " + inputStr + "\n\r" + "decryption: " + outputStr);
          assertEquals(inputStr, outputStr);
     }

     @Test
     public void testSign() throws Exception {
          System.out.println("private encryption——public decryption");
          String inputStr = "hello, kiko.";
          byte[] data = inputStr.getBytes();

          byte[] encodedData = RSACoder.encryptByPrivateKey(data, privateKey);

          byte[] decodedData = RSACoder
                    .decryptByPublicKey(encodedData, publicKey);

          String outputStr = new String(decodedData);
          System.out.println("original: " + inputStr + "\n\r" + "decryption: " + outputStr);
          assertEquals(inputStr, outputStr);

          System.out.println("private signature——public validate the signature");
          // generate signature
          String sign = RSACoder.sign(encodedData, privateKey);
          System.out.println("singature string :\r" + sign);

          // validate signature string
          boolean status = RSACoder.verify(encodedData, publicKey, sign);
          System.out.println("status:\r" + status);
          assertTrue(status);
     }
}


references:
http://snowolf.iteye.com/blog/381767

猜你喜欢

转载自sillycat.iteye.com/blog/1469296
RSA
今日推荐