Base 64, MD5, RSA 와 ASE 암호 화 알고리즘 총화 및 JAVA 실현 - RSA

일반적인 암호 화 알고리즘
흔히 볼 수 있 는 암호 화 알고리즘 은 세 가지 로 나 눌 수 있 는데 대칭 암호 화 알고리즘, 비대 칭 암호 화 알고리즘 과 Hash 알고리즘 이다.
비대 칭 암호 화 알고리즘
비대 칭 암호 화 알고리즘 은 두 개의 키 가 필요 합 니 다. 공개 키 (publickey) 와 개인 키 (privatekey) 입 니 다.공개 키 와 개인 키 는 한 쌍 입 니 다. 공개 키 로 데 이 터 를 암호 화하 면 해당 하 는 개인 키 로 만 복호화 할 수 있 습 니 다.개인 키 로 데 이 터 를 암호 화하 면 공개 키 로 만 복호화 할 수 있 습 니 다.암호 화 와 복호화 가 서로 다른 키 를 사용 하기 때문에 이 알고리즘 을 비대 칭 암호 화 알고리즘 이 라 고 합 니 다.흔히 볼 수 있 는 비대 칭 알고리즘 은 RSA, Elgamal 등 알고리즘 을 포함한다.
RSA 알고리즘
RSA 는 현재 가장 영향력 이 있 는 공개 키 암호 화 알고리즘 입 니 다. 이 알고리즘 은 매우 간단 한 수론 사실 을 바탕 으로 합 니 다. 두 개의 큰 소 수 를 곱 하 는 것 은 매우 쉽 지만 그 때 는 그 곱 하기 를 인수 분해 하기 가 매우 어 려 웠 기 때문에 곱 하기 공 개 를 암호 화 키, 즉 공개 키 로 할 수 있 고 두 개의 큰 소수 그룹 은 비밀 키 를 합성 할 수 있 습 니 다.공개 키 는 발표 할 수 있 는 사람 이 사용 할 수 있 는 것 이 고 비밀 키 는 자신의 소유 이 며 복호화 에 사용 할 수 있 습 니 다.프로 세 스:
4. 567917. 두 개의 큰 질 수 p 와 q 를 마음대로 선택 하고 p 는 q 와 같 지 않 으 며 N = pq 를 계산한다
4. 567917. 오로라 함수 에 따라 N 보다 크 지 않 고 N 과 서로 질 적 인 정수 개 수 는 (p - 1) (q - 1) 이다
4. 567917. 정수 e 와 (p - 1) (q - 1) 의 상호 질 을 선택 하고 e 는 (p - 1) (q - 1) 보다 작다
4. 567917. 다음 과 같은 공식 으로 d: d 를 계산한다.× e ≡ 1 (mod (p-1)(q-1))。
p 와 q 의 기록 을 소각 합 니 다
(N, e) 는 공개 키 이 고 (N, d) 는 비밀 키 입 니 다.
JAVA 실현
public class RSAUtils {

    public static final String CHARSET = "UTF-8";
    public static final String RSA_ALGORITHM = "RSA";

    public static Map createKeys(int keySize){
        // RSA      KeyPairGenerator  
        KeyPairGenerator kpg;
        try{
            kpg = KeyPairGenerator.getInstance(RSA_ALGORITHM);
        }catch(NoSuchAlgorithmException e){
            throw new IllegalArgumentException("No such algorithm-->[" + RSA_ALGORITHM + "]");
        }

        //   KeyPairGenerator  ,    
        kpg.initialize(keySize);
        //     
        KeyPair keyPair = kpg.generateKeyPair();
        //    
        Key publicKey = keyPair.getPublic();
        //Base64  
        String publicKeyStr = Base64Utils.getEncoder().encodeToString(publicKey.getEncoded());
        //    
        Key privateKey = keyPair.getPrivate();
        //Base64  
        String privateKeyStr = Base64Utils.getEncoder().encodeToString(privateKey.getEncoded());
        Map keyPairMap = new HashMap();
        keyPairMap.put("publicKey", publicKeyStr);
        keyPairMap.put("privateKey", privateKeyStr);

        return keyPairMap;
    }

    /**
     *     
     * @param publicKey      (  base64  )
     * @throws Exception
     */
    public static RSAPublicKey getPublicKey(String publicKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
        //  X509   Key        
        KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
        //Base64  
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec( Base64Utils.getDecoder().decode(publicKey));
        RSAPublicKey key = (RSAPublicKey) keyFactory.generatePublic(x509KeySpec);
        return key;
    }

    /**
     *     
     * @param privateKey      (  base64  )
     * @throws Exception
     */
    public static RSAPrivateKey getPrivateKey(String privateKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
        //  PKCS#8   Key        
        KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
        //Base64  
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(Base64Utils.getDecoder().decode(privateKey));
        RSAPrivateKey key = (RSAPrivateKey) keyFactory.generatePrivate(pkcs8KeySpec);
        return key;
    }

    /**
     *     
     * @param data
     * @param publicKey
     * @return
     */
    public static String publicEncrypt(String data, RSAPublicKey publicKey){
        try{
            Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            return Base64Utils.getEncoder().encodeToString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes(CHARSET), publicKey.getModulus().bitLength()));
        }catch(Exception e){
           throw new RuntimeException("    :" + data + ",    ", e);
        }
    }

    /**
     *     
     * @param data
     * @param privateKey
     * @return
     */

    public static String privateDecrypt(String data, RSAPrivateKey privateKey){
        try{
            Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64Utils.getDecoder().decode(data), privateKey.getModulus().bitLength()), CHARSET);
        }catch(Exception e){
            throw new RuntimeException("    :" + data + ",    ", e);
        }
    }
    private static byte[] rsaSplitCodec(Cipher cipher, int opmode, byte[] datas, int keySize){
        int maxBlock = 0;
        if(opmode == Cipher.DECRYPT_MODE){
            maxBlock = keySize / 8;
        }else{
            maxBlock = keySize / 8 - 11;
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] buff;
        int i = 0;
        try{
            while(datas.length > offSet){
                if(datas.length-offSet > maxBlock){
                    buff = cipher.doFinal(datas, offSet, maxBlock);
                }else{
                    buff = cipher.doFinal(datas, offSet, datas.length-offSet);
                }
                out.write(buff, 0, buff.length);
                i++;
                offSet = i * maxBlock;
            }
        }catch(Exception e){
             throw new RuntimeException("          ", e);
        }finally {
            try {
                out.flush();
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        byte[] resultDatas = out.toByteArray();
        return resultDatas;
    }
}

좋은 웹페이지 즐겨찾기