RSAデータ暗号解読


RSAは非対称のデータ暗号化アルゴリズムで、彼は2対の鍵を持っていて、それぞれ公開鍵と秘密鍵で、公開鍵暗号化は秘密鍵でしか復号できなくて、それに対応する秘密鍵は暗号化して、公開鍵でしか復号できません.これにより、一定の安全性が保証されます.
RSAの用途は2つあります.-銀行カード、身分証明書、携帯電話番号など、データの暗号化と復号化に敏感な情報を暗号化します.-チェックマークとチェックマークは、パブリックネットワークでデータを転送する必要がある場合に多く使用されます.httpsを含むコア原理もそうです.
httpsの動作原理はhttps暗号化通信プロセスの図解を参照することができる
show me the code
package com.netfinworks.mag.util.sign;

import org.apache.commons.codec.binary.Base64;

import java.io.UnsupportedEncodingException;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.xml.bind.DatatypeConverter;

/**
 * Created by mazhenhua on 2017/05/06.
 */
public class RSATest {



    /**
     *     
     */
    public static final String SIGNATURE_ALGORITHM = "SHA1withRSA";


    private static byte[] h2b(String hex){
        return DatatypeConverter.parseHexBinary(hex);
    }
    private static String b2h(byte[] bytes){
        return DatatypeConverter.printHexBinary(bytes);
    }

    private static SecureRandom sr = new SecureRandom();

    public static KeyPair newKeyPair(int rsabits) throws NoSuchAlgorithmException {
        KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
        generator.initialize(rsabits, sr);
        return generator.generateKeyPair();
    }

    public static byte[] pubKeyToBytes(PublicKey key){
        return key.getEncoded(); // X509 for a public key
    }
    public static byte[] privKeyToBytes(PrivateKey key){
        return key.getEncoded(); // PKCS8 for a private key
    }

    public static PublicKey bytesToPubKey(byte[] bytes) throws InvalidKeySpecException, NoSuchAlgorithmException{
        return KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(bytes));
    }
    public static PrivateKey bytesToPrivKey(byte[] bytes) throws InvalidKeySpecException, NoSuchAlgorithmException{
        return KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(bytes));
    }

    public static byte[] encryptWithPubKey(byte[] input, PublicKey key) throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException {
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        return cipher.doFinal(input);
    }
    public static byte[] decryptWithPrivKey(byte[] input, PrivateKey key) throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException {
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.DECRYPT_MODE, key);
        return cipher.doFinal(input);
    }

    private static byte[] getContentBytes(String content, String charset) {
        if (charset == null || "".equals(charset)) {
            return content.getBytes();
        }
        try {
            return content.getBytes(charset);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("         ,        ,          :" + charset);
        }
    }

    /**
     *
     * @param text      
     * @param sign    
     * @param publicKey   
     * @param charset     
     * @return
     * @throws Exception
     */
    public static boolean verify(String text, String sign, PublicKey publicKey, String charset) throws Exception {
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        signature.initVerify(publicKey);
        signature.update(getContentBytes(text, charset));
        return signature.verify(Base64.decodeBase64(sign));
    }

    /**
     *
     * @param text      
     * @param privateK   
     * @param charset     
     * @return
     * @throws Exception
     */
    public static String sign(String text, PrivateKey privateK, String charset) throws Exception {
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        signature.initSign(privateK);
        signature.update(getContentBytes(text, charset));
        byte[] result = signature.sign();
        return Base64.encodeBase64String(result);
    }

    public static void main(String[] args) throws Exception {
        KeyPair kp = newKeyPair(1<<11); // 2048 bit RSA; might take a second to generate keys
        PublicKey pubKey = kp.getPublic();
        PrivateKey privKey = kp.getPrivate();
        String plainText = "Dear Bob,
Wish you were here.
\t--Alice"
; byte[] cipherText = encryptWithPubKey(plainText.getBytes("UTF-8"),pubKey); System.out.println("cipherText: "+b2h(cipherText)); System.out.println("plainText:"); System.out.println(new String(decryptWithPrivKey(cipherText,privKey),"UTF-8")); } }

mainメソッドでは、復号化するしかなく、チェックマークを付ける方法を追加しました.
ここで用いる鍵対はいずれも自己生成の2048ビット長であり,一般にbase 64後の文字列,あるいは購入した鍵対証明書が用いられる.この鍵は自分でJDKで生成することもでき、ネット上では多くの方法があります.
多くのサイトでは1024を長さの鍵として使っていますが、多くの同僚の1024を聞いたことがあります.2048を長さとする鍵を推奨します.
鍵の長さが長ければ長いほど暗号化の複雑さが高くなり、それに応じて解読が困難になり、理論的には鍵が一定の長さに達すると解読されない.
参考資料:stackoverflow