자바 에서 자주 사용 하 는 암호 화 알고리즘 을 정리 하 다.

1.암호 화 알고리즘 분류
암호 화 알고리즘 은 보통 세 가지 로 나 뉜 다.
대칭 암호 화
암호 화 와 복호화 가 같은 키 를 사용 하 는 암호 화 알고리즘 을 말 합 니 다.대칭 암호 화 알고리즘 의 장점 은 복호화 효율 이 높 고 실현 하기 쉽다 는 것 이다.
역 암호 화
역 암호 화 되 지 않 는 알고리즘 은 암호 화 과정 에서 키 가 필요 하지 않 고 암호 화 된 데 이 터 를 복호화 할 수 없 으 며 같은 입력 데이터 가 같은 역 알고리즘 을 거 쳐 야 같은 암호 화 데 이 터 를 얻 을 수 있다 는 것 이 특징 이다.
비대 칭 암호 화
암호 화 와 복호화 가 서로 다른 키 를 사용 하 는 암호 화 알고리즘 을 말 하 며 공개 키 암호 화 라 고도 합 니 다.
2.암호 화 알고리즘 의 응용
1.디지털 서명:인증 과 데이터 완전 성 검증 을 하고 비대 칭 키 암호 화 기술 과 디지털 요약 기술 을 사용 합 니 다.
2.디지털 인증서:주로 디지털 서명 을 확보 하 는 것 이 안전 하고 효과 적 이 며 디지털 인증 서 는 독립 된 인증서 발행 기구 에서 발표 합 니 다.디지털 인증 서 는 각각 다 릅 니 다.각 인증 서 는 서로 다른 등급 의 신뢰 도 를 제공 할 수 있 습 니 다.이 인증 서 는 사용자 의 개인 정보 와 그의 공개 키 정 보 를 포함 하고 인증 센터 의 서명 정보 도 첨부 되 어 있 습 니 다.
3.MD5:사용자 암 호 를 암호 화하 고 저장 합 니 다.
4.네트워크 데이터 암호 화:전송 하 는 데이터 의 안전 을 보장 하고 메시지 가 캡 처 되 더 라 도 밀 스푼 이 없 는 상태 에서 메시지 의 실제 내용 을 알 수 없습니다.
5.SSL 프로 토 콜:악수 단계 에서 비대 칭 암호 화 를 사용 하고 전송 단계 에서 대칭 암호 화 를 사용 합 니 다.즉,SSL 에서 전 송 된 데 이 터 는 대칭 키 로 암호 화 된 것 입 니 다.또한 HTTPS 는 SSL+HTTP 프로 토 콜 로 구 축 된 암호 화 전송,인증(클 라 이언 트 가 연 결 된 대상 호스트 가 실제 호스트 인지 확인)을 할 수 있 는 네트워크 프로 토 콜 이기 도 합 니 다.
3.대칭 암호 화 알고리즘 실현
  • 장점:알고리즘 은 메시지 쌍방 에 공개 되 고 계 산 량 이 적 으 며 암호 화 속도 가 빠 르 고 암호 화 효율 이 높다.
  • 단점:데이터 전송 전에 발송 자 와 수신 자 는 비밀 키 를 협의 한 다음 에 쌍방 이 비밀 키 를 저장 해 야 합 니 다.한 측의 비밀 키 가 누설 되면 암호 화 된 정보 가 해 제 됩 니 다.
  • 3.1 DES 소개
    DES 는 모두 Data Encryption Standard,즉 데이터 암호 화 표준 이 라 고 불 리 며 키 암호 화 를 사용 하 는 블록 알고리즘 으로 1977 년 미국 연방정부 의 국가 표준 국 에 의 해 연방 자료 처리 표준(FIPS)으로 확정 되 고 비 밀 급 정부 통신 에서 사용 할 수 있 는 권한 을 수 여 받 은 후 이 계산법 이 국제 적 으로 널리 퍼 졌 다.하지만 지금 은 좀 시대 에 뒤떨어 졌 다.
    Java 코드 구현:
    
    import java.io.UnsupportedEncodingException;
    import java.security.SecureRandom;
    import javax.crypto.spec.DESKeySpec;
    import javax.crypto.SecretKeyFactory;
    import javax.crypto.SecretKey;
    import javax.crypto.Cipher;
    
    /**
     * DES     DES         ,         :              。DES      IBM   ,
     *            ,        ,           ,  DES  56   ,       ,
     * 24        。    ,        ,        DES    ,      DES JAVA   。
     *   :DES        ,        8   
     */
    public class DesDemo {
    	public DesDemo() {
    	}
    
    	//   
    	public static void main(String args[]) {
    		//      
    		String str = "cryptology";
    		//   ,    8   
    		String password = "95880288";
    
    		byte[] result;
    		try {
    			result = DesDemo.encrypt(str.getBytes(), password);
    			System.out.println("   :" + result);
    			byte[] decryResult = DesDemo.decrypt(result, password);
    			System.out.println("   :" + new String(decryResult));
    		} catch (UnsupportedEncodingException e2) {
    			// TODO Auto-generated catch block
    			e2.printStackTrace();
    		} catch (Exception e1) {
    			e1.printStackTrace();
    		}
    	}
    
    	//          
    
    	/**
    	 *   
    	 * 
    	 * @param datasource
    	 *            byte[]
    	 * @param password
    	 *            String
    	 * @return byte[]
    	 */
    	public static byte[] encrypt(byte[] datasource, String password) {
    		try {
    			SecureRandom random = new SecureRandom();
    			DESKeySpec desKey = new DESKeySpec(password.getBytes());
    			//         ,     DESKeySpec   
    			SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
    			SecretKey securekey = keyFactory.generateSecret(desKey);
    			// Cipher          
    			Cipher cipher = Cipher.getInstance("DES");
    			//       Cipher  ,ENCRYPT_MODE    Cipher            
    			cipher.init(Cipher.ENCRYPT_MODE, securekey, random);
    			//   ,       
    			//         
    			return cipher.doFinal(datasource); //              ,           
    		} catch (Throwable e) {
    			e.printStackTrace();
    		}
    		return null;
    	}
    
    	/**
    	 *   
    	 * 
    	 * @param src
    	 *            byte[]
    	 * @param password
    	 *            String
    	 * @return byte[]
    	 * @throws Exception
    	 */
    	public static byte[] decrypt(byte[] src, String password) throws Exception {
    		// DES               
    		SecureRandom random = new SecureRandom();
    		//     DESKeySpec  
    		DESKeySpec desKey = new DESKeySpec(password.getBytes());
    		//         
    		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");//          
    																			// Cipher
    																			//   
    		//  DESKeySpec     SecretKey  
    		SecretKey securekey = keyFactory.generateSecret(desKey);
    		// Cipher          
    		Cipher cipher = Cipher.getInstance("DES");
    		//       Cipher  
    		cipher.init(Cipher.DECRYPT_MODE, securekey, random);
    		//         
    		return cipher.doFinal(src);
    	}
    }
    
    3.2 IDEA 소개
  •  이 알고리즘 은 DES 알고리즘 을 바탕 으로 발 전 된 것 으로 삼중 DES 와 유사 합 니 다.
  • IDEA 를 발전 시 킨 것 도 DES 가 키 가 너무 짧다 는 단점 을 느 꼈 기 때 문 입 니 다.
  • DEA 키 는 128 비트 입 니 다.이렇게 긴 키 는 앞으로 몇 년 동안 안전 할 것 입 니 다.
  • 실제 프로젝트 에 사용 되 는 것 이 적 으 면 됩 니 다.
  •  자바 코드 구현
    
    import java.security.Key;
    import java.security.Security;
    
    import javax.crypto.Cipher;
    import javax.crypto.KeyGenerator;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.SecretKeySpec;
    
    import org.apache.commons.codec.binary.Base64;
    import org.bouncycastle.jce.provider.BouncyCastleProvider;
    
    public class IDEADemo {
    	public static void main(String args[]) {
    		bcIDEA();
    	}
    	public static void bcIDEA() {
    	    String src = "www.xttblog.com security idea";
    	    try {
    	        Security.addProvider(new BouncyCastleProvider());
    	         
    	        //  key
    	        KeyGenerator keyGenerator = KeyGenerator.getInstance("IDEA");
    	        keyGenerator.init(128);
    	        SecretKey secretKey = keyGenerator.generateKey();
    	        byte[] keyBytes = secretKey.getEncoded();
    	         
    	        //    
    	        Key key = new SecretKeySpec(keyBytes, "IDEA");
    	         
    	        //  
    	        Cipher cipher = Cipher.getInstance("IDEA/ECB/ISO10126Padding");
    	        cipher.init(Cipher.ENCRYPT_MODE, key);
    	        byte[] result = cipher.doFinal(src.getBytes());
    	        System.out.println("bc idea encrypt : " + Base64.encodeBase64String(result));
    	         
    	        //  
    	        cipher.init(Cipher.DECRYPT_MODE, key);
    	        result = cipher.doFinal(result);
    	        System.out.println("bc idea decrypt : " + new String(result));
    	    } catch (Exception e) {
    	        e.printStackTrace();
    	    }
    	}
    }
    
    
    4.불가 역 암호 화 알고리즘
  • 장점:거 스 를 수 없고 계산 하기 쉬 우 며 특징 화
  • 단점:해시 충돌 이 있 을 수 있 습 니 다
  • 4.1 MD5 소개
    MD5 는 대 용량 정 보 를 디지털 서명 소프트웨어 로 개인 키 에 서명 하기 전에 비밀 형식 으로 압축 하 는 역할 을 합 니 다.
    (즉,임의의 길이 의 바이트 문자열 을 일정한 길이 의 16 진수 문자열 로 바 꾸 는 것 이다.)
    주로 다음 과 같은 특징 이 있다.
  • 1.압축성:임의의 길이 의 데이터,계 산 된 MD5 값 의 길 이 는 모두 고정 되 어 있 습 니 다.
  • 2.계산 하기 쉽다:원 데이터 에서 MD5 값 을 계산 하 는 것 은 매우 쉽다.
  • 3.수정 저항 성:원본 데 이 터 를 변경 할 때 1 바이트 만 수정 하 더 라 도 얻 은 MD5 값 은 큰 차이 가 있 습 니 다.
  • 4.충돌 저항:원래 데이터 와 MD5 값 을 알 고 있 습 니 다.같은 MD5 값 을 가 진 데이터(즉,데이터 위조)를 찾 는 것 은 매우 어렵 습 니 다.
  • 자바 코드 구현
    
    import java.security.MessageDigest;
    
    //  JDK  java.security.MessageDigest   MD5  
    public class MD5Demo {
    
        public static void main(String[] args) {
            System.out.println(getMD5Code("       "));
        }
    
        private MD5Demo() {
        }
    
        // md5  
        public static String getMD5Code(String message) {
            String md5Str = "";
            try {
            	//  MD5      
                MessageDigest md = MessageDigest.getInstance("MD5");
                //           
                byte[] md5Bytes = md.digest(message.getBytes());
                md5Str = bytes2Hex(md5Bytes);
            }catch(Exception e) {
                e.printStackTrace();
            }
            return md5Str;
        }
    
        // 2   16  
        public static String bytes2Hex(byte[] bytes) {
            StringBuffer result = new StringBuffer();
            int temp;
            try {
                for (int i = 0; i < bytes.length; i++) {
                    temp = bytes[i];
                    if(temp < 0) {
                        temp += 256;
                    }
                    if (temp < 16) {
                        result.append("0");
                    }
                    result.append(Integer.toHexString(temp));
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return result.toString();
        }
    }
    
    4.2 SHA 1 소개
    길이 가 2^64 비트 이하 인 메시지 에 대해 SHA 1 은 160 비트(40 글자)의 메시지 요약 을 생 성 합 니 다.메 시 지 를 받 았 을 때 이 메시지 요약 은 데이터 의 완전 성 을 검증 하 는 데 사용 할 수 있다.전송 과정 에서 데이터 가 변 할 수 있 으 므 로 이 럴 때 서로 다른 메시지 요약 이 생 길 수 있 습 니 다.
    SHA 1 은 다음 과 같은 특성 이 있 습 니 다.
  • 메시지 요약 에서 정 보 를 복원 할 수 없습니다.
  • 두 개의 서로 다른 소식 은 같은 소식 요약 이 나 오지 않 습 니 다.(단,1x 10^48 분 의 1 의 확률 로 같은 소식 요약 이 나 올 수 있 습 니 다.일반적으로 사용 할 때 무시 합 니 다)
  •  자바 코드 구현
    
    import java.io.UnsupportedEncodingException;
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    
    public class SHA1Demo {
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		System.out.println(getSha1("       "));
    	
    	}
    
    	public static String getSha1(String str) {
    		if (null == str || 0 == str.length()) {
    			return null;
    		}
    		char[] hexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
    		try {
    			//  SHA1        
    			MessageDigest mdTemp = MessageDigest.getInstance("SHA1");
    			//             。
    			mdTemp.update(str.getBytes("UTF-8"));
    			//           
    			byte[] md = mdTemp.digest();
    			//SHA1            
    			int j = md.length;
    		    char[] buf = new char[j * 2];
    			int k = 0;
    			for (int i = 0; i < j; i++) {
    				byte byte0 = md[i];
    				buf[k++] = hexDigits[byte0 >>> 4 & 0xf];
    				buf[k++] = hexDigits[byte0 & 0xf];
    			}
    			return new String(buf);
    		} catch (NoSuchAlgorithmException e) {
    			e.printStackTrace();
    		} catch (UnsupportedEncodingException e) {
    			e.printStackTrace();
    		}
    		return "0";
    		
    	}
    }
    
    
    4.3 HMAC 소개
    HMAC 는 키 와 관련 된 해시 연산 메시지 인증 코드(Hash-based Message Authentication Code)로 HMAC 연산 은 해시 알고리즘(MD5,SHA 1 등)을 이용 하여 하나의 키 와 하나의 메 시 지 를 입력 하여 메시지 요약 을 생 성하 여 출력 한다.
    HMAC 발송 자 와 수신 자가 모두 가지 고 있 는 key 를 계산 합 니 다.이 key 가 없 는 제3자 가 정확 한 해시 값 을 계산 할 수 없습니다.그러면 데이터 가 변경 되 는 것 을 방지 할 수 있 습 니 다.
    자바 코드 구현
    
    import net.pocrd.annotation.NotThreadSafe;
    import net.pocrd.define.ConstField;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import javax.crypto.Mac;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.SecretKeySpec;
    import java.util.Arrays;
    
    
    @NotThreadSafe
    public class HMacHelper {
        private static final Logger logger = LoggerFactory.getLogger(HMacHelper.class);
        private Mac mac;
    
        /**
         * MAC          
         * HmacMD5/HmacSHA1/HmacSHA256/HmacSHA384/HmacSHA512
         */
        private static final String KEY_MAC = "HmacMD5";
        public HMacHelper(String key) {
            try {
                SecretKey secretKey = new SecretKeySpec(key.getBytes(ConstField.UTF8), KEY_MAC);
                mac = Mac.getInstance(secretKey.getAlgorithm());
                mac.init(secretKey);
            } catch (Exception e) {
                logger.error("create hmac helper failed.", e);
            }
        }
        public byte[] sign(byte[] content) {
            return mac.doFinal(content);
        }
    
        public boolean verify(byte[] signature, byte[] content) {
            try {
                byte[] result = mac.doFinal(content);
                return Arrays.equals(signature, result);
            } catch (Exception e) {
                logger.error("verify sig failed.", e);
            }
            return false;
        }
    }
    
    5.비대 칭 암호 화
  • 장점:비대 칭 암호 화 는 대칭 암호 화 에 비해 안전성 이 좋 고 비밀 키 가 누설 되 지 않 으 면 해독 되 기 어렵다.
  • 단점:암호 화 와 복호화 가 오래 걸 리 고 속도 가 느 려 서 소량의 데이터 만 암호 화 할 수 있 습 니 다.
  • 5.1 RSA 소개
    RSA 는 현재 가장 영향력 있 고 자주 사용 되 는 공개 키 암호 화 알고리즘 이다.이 는 지금까지 알려 진 대부분의 암호 공격 에 저항 할 수 있 으 며 ISO 에서 공개 키 데이터 암호 화 기준 으로 추천 되 었 습 니 다.RSA 공개 키 암호 시스템 의 원 리 는 수론 에 따 르 면 두 개의 큰 소 수 를 찾 는 것 이 간단 하지만 이들 의 곱 하기 를 인수 분해 하 는 것 은 매우 어렵 기 때문에 곱 하기 공 개 를 암호 화 키 로 할 수 있다 는 것 이다.
    자바 코드 구현
    
    import org.apache.commons.codec.binary.Base64;
    
    import java.security.*;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.spec.X509EncodedKeySpec;
    import java.util.HashMap;
    import java.util.Map;
    
    import javax.crypto.Cipher;
    
    /**
     * Created by humf.     commons-codec  
     */
    public class RSADemo {
    
    	public static void main(String[] args) throws Exception {
    		Map<String, Key> keyMap = initKey();
    		String publicKey = getPublicKey(keyMap);
    		String privateKey = getPrivateKey(keyMap);
    
    		System.out.println(keyMap);
    		System.out.println("-----------------------------------");
    		System.out.println(publicKey);
    		System.out.println("-----------------------------------");
    		System.out.println(privateKey);
    		System.out.println("-----------------------------------");
    		byte[] encryptByPrivateKey = encryptByPrivateKey("123456".getBytes(), privateKey);
    		byte[] encryptByPublicKey = encryptByPublicKey("123456", publicKey);
    		System.out.println(encryptByPrivateKey);
    		System.out.println("-----------------------------------");
    		System.out.println(encryptByPublicKey);
    		System.out.println("-----------------------------------");
    		String sign = sign(encryptByPrivateKey, privateKey);
    		System.out.println(sign);
    		System.out.println("-----------------------------------");
    		boolean verify = verify(encryptByPrivateKey, publicKey, sign);
    		System.out.println(verify);
    		System.out.println("-----------------------------------");
    		byte[] decryptByPublicKey = decryptByPublicKey(encryptByPrivateKey, publicKey);
    		byte[] decryptByPrivateKey = decryptByPrivateKey(encryptByPublicKey, privateKey);
    		System.out.println(decryptByPublicKey);
    		System.out.println("-----------------------------------");
    		System.out.println(decryptByPrivateKey);
    
    	}
    
    	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";
    
    	public static byte[] decryptBASE64(String key) {
    		return Base64.decodeBase64(key);
    	}
    
    	public static String encryptBASE64(byte[] bytes) {
    		return Base64.encodeBase64String(bytes);
    	}
    
    	/**
    	 *             
    	 *
    	 * @param data
    	 *                
    	 * @param privateKey
    	 *              
    	 * @return
    	 * @throws Exception
    	 */
    	public static String sign(byte[] data, String privateKey) throws Exception {
    		//    base64     
    		byte[] keyBytes = decryptBASE64(privateKey);
    		//   PKCS8EncodedKeySpec  
    		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
    		// KEY_ALGORITHM        
    		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
    		//       
    		PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
    		//             
    		Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
    		signature.initSign(priKey);
    		signature.update(data);
    		return encryptBASE64(signature.sign());
    	}
    
    	/**
    	 *       
    	 *
    	 * @param data
    	 *                
    	 * @param publicKey
    	 *              
    	 * @param sign
    	 *                
    	 * @return       true     false
    	 * @throws Exception
    	 */
    	public static boolean verify(byte[] data, String publicKey, String sign) throws Exception {
    		//    base64     
    		byte[] keyBytes = decryptBASE64(publicKey);
    		//   X509EncodedKeySpec  
    		X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
    		// KEY_ALGORITHM        
    		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
    		//       
    		PublicKey pubKey = keyFactory.generatePublic(keySpec);
    		Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
    		signature.initVerify(pubKey);
    		signature.update(data);
    		//         
    		return signature.verify(decryptBASE64(sign));
    	}
    
    	public static byte[] decryptByPrivateKey(byte[] data, String key) throws Exception {
    		//      
    		byte[] keyBytes = decryptBASE64(key);
    		//     
    		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
    		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
    		Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
    		//      
    		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
    		cipher.init(Cipher.DECRYPT_MODE, privateKey);
    		return cipher.doFinal(data);
    	}
    
    	/**
    	 *   <br>
    	 *      
    	 *
    	 * @param data
    	 * @param key
    	 * @return
    	 * @throws Exception
    	 */
    	public static byte[] decryptByPrivateKey(String data, String key) throws Exception {
    		return decryptByPrivateKey(decryptBASE64(data), key);
    	}
    
    	/**
    	 *   <br>
    	 *      
    	 *
    	 * @param data
    	 * @param key
    	 * @return
    	 * @throws Exception
    	 */
    	public static byte[] decryptByPublicKey(byte[] data, String key) throws Exception {
    		//      
    		byte[] keyBytes = decryptBASE64(key);
    		//     
    		X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
    		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
    		Key publicKey = keyFactory.generatePublic(x509KeySpec);
    		//      
    		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
    		cipher.init(Cipher.DECRYPT_MODE, publicKey);
    		return cipher.doFinal(data);
    	}
    
    	/**
    	 *   <br>
    	 *      
    	 *
    	 * @param data
    	 * @param key
    	 * @return
    	 * @throws Exception
    	 */
    	public static byte[] encryptByPublicKey(String data, String key) throws Exception {
    		//      
    		byte[] keyBytes = decryptBASE64(key);
    		//     
    		X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
    		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
    		Key publicKey = keyFactory.generatePublic(x509KeySpec);
    		//      
    		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
    		cipher.init(Cipher.ENCRYPT_MODE, publicKey);
    		return cipher.doFinal(data.getBytes());
    	}
    
    	/**
    	 *   <br>
    	 *      
    	 *
    	 * @param data
    	 * @param key
    	 * @return
    	 * @throws Exception
    	 */
    	public static byte[] encryptByPrivateKey(byte[] data, String key) throws Exception {
    		//      
    		byte[] keyBytes = decryptBASE64(key);
    		//     
    		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
    		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
    		Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
    		//      
    		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
    		cipher.init(Cipher.ENCRYPT_MODE, privateKey);
    		return cipher.doFinal(data);
    	}
    
    	/**
    	 *     
    	 *
    	 * @param keyMap
    	 * @return
    	 * @throws Exception
    	 */
    	public static String getPrivateKey(Map<String, Key> keyMap) throws Exception {
    		Key key = (Key) keyMap.get(PRIVATE_KEY);
    		return encryptBASE64(key.getEncoded());
    	}
    
    	/**
    	 *     
    	 *
    	 * @param keyMap
    	 * @return
    	 * @throws Exception
    	 */
    	public static String getPublicKey(Map<String, Key> keyMap) throws Exception {
    		Key key = keyMap.get(PUBLIC_KEY);
    		return encryptBASE64(key.getEncoded());
    	}
    
    	/**
    	 *      
    	 *
    	 * @return
    	 * @throws Exception
    	 */
    	public static Map<String, Key> initKey() throws Exception {
    		KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
    		keyPairGen.initialize(1024);
    		KeyPair keyPair = keyPairGen.generateKeyPair();
    		Map<String, Key> keyMap = new HashMap(2);
    		keyMap.put(PUBLIC_KEY, keyPair.getPublic());//   
    		keyMap.put(PRIVATE_KEY, keyPair.getPrivate());//   
    		return keyMap;
    	}
    
    }
    
    5.2 ECC 소개ECC도 비대 칭 암호 화 알고리즘 입 니 다.주요 장점 은 어떤 상황 에서 다른 방법 보다 더 작은 키 를 사용 하 는 것 입 니 다.예 를 들 어RSA암호 화 알고리즘 은 상당 하거나 높 은 등급 의 안전 등급 을 제공 합 니 다.그러나 하나의 단점 은 암호 화 와 복호화 작업 의 실현 이 다른 메커니즘 보다 길 다 는 것 이다(RSA알고리즘 에 비해 이 알고리즘 은CPU소모 가 심각 하 다).
    자바 코드 구현
    
    import net.pocrd.annotation.NotThreadSafe;
    import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey;
    import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
    import org.bouncycastle.jce.provider.BouncyCastleProvider;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import javax.crypto.Cipher;
    import java.io.ByteArrayOutputStream;
    import java.security.KeyFactory;
    import java.security.Security;
    import java.security.Signature;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.spec.X509EncodedKeySpec;
    
    @NotThreadSafe
    public class EccHelper {
        private static final Logger logger = LoggerFactory.getLogger(EccHelper.class);
        private static final int SIZE = 4096;
        private BCECPublicKey  publicKey;
        private BCECPrivateKey privateKey;
    
        static {
            Security.addProvider(new BouncyCastleProvider());
        }
    
        public EccHelper(String publicKey, String privateKey) {
            this(Base64Util.decode(publicKey), Base64Util.decode(privateKey));
        }
    
        public EccHelper(byte[] publicKey, byte[] privateKey) {
            try {
                KeyFactory keyFactory = KeyFactory.getInstance("EC", "BC");
                if (publicKey != null && publicKey.length > 0) {
                    this.publicKey = (BCECPublicKey)keyFactory.generatePublic(new X509EncodedKeySpec(publicKey));
                }
                if (privateKey != null && privateKey.length > 0) {
                    this.privateKey = (BCECPrivateKey)keyFactory.generatePrivate(new PKCS8EncodedKeySpec(privateKey));
                }
            } catch (ClassCastException e) {
                throw new RuntimeException("", e);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    
        public EccHelper(String publicKey) {
            this(Base64Util.decode(publicKey));
        }
    
        public EccHelper(byte[] publicKey) {
            try {
                KeyFactory keyFactory = KeyFactory.getInstance("EC", "BC");
                if (publicKey != null && publicKey.length > 0) {
                    this.publicKey = (BCECPublicKey)keyFactory.generatePublic(new X509EncodedKeySpec(publicKey));
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    
        public byte[] encrypt(byte[] content) {
            if (publicKey == null) {
                throw new RuntimeException("public key is null.");
            }
            try {
                Cipher cipher = Cipher.getInstance("ECIES", "BC");
                cipher.init(Cipher.ENCRYPT_MODE, publicKey);
                int size = SIZE;
                ByteArrayOutputStream baos = new ByteArrayOutputStream((content.length + size - 1) / size * (size + 45));
                int left = 0;
                for (int i = 0; i < content.length; ) {
                    left = content.length - i;
                    if (left > size) {
                        cipher.update(content, i, size);
                        i += size;
                    } else {
                        cipher.update(content, i, left);
                        i += left;
                    }
                    baos.write(cipher.doFinal());
                }
                return baos.toByteArray();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    
        public byte[] decrypt(byte[] secret) {
            if (privateKey == null) {
                throw new RuntimeException("private key is null.");
            }
            try {
                Cipher cipher = Cipher.getInstance("ECIES", "BC");
                cipher.init(Cipher.DECRYPT_MODE, privateKey);
                int size = SIZE + 45;
                ByteArrayOutputStream baos = new ByteArrayOutputStream((secret.length + size + 44) / (size + 45) * size);
                int left = 0;
                for (int i = 0; i < secret.length; ) {
                    left = secret.length - i;
                    if (left > size) {
                        cipher.update(secret, i, size);
                        i += size;
                    } else {
                        cipher.update(secret, i, left);
                        i += left;
                    }
                    baos.write(cipher.doFinal());
                }
                return baos.toByteArray();
            } catch (Exception e) {
                logger.error("ecc decrypt failed.", e);
            }
            return null;
        }
    
        public byte[] sign(byte[] content) {
            if (privateKey == null) {
                throw new RuntimeException("private key is null.");
            }
            try {
                Signature signature = Signature.getInstance("SHA1withECDSA", "BC");
                signature.initSign(privateKey);
                signature.update(content);
                return signature.sign();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    
        public boolean verify(byte[] sign, byte[] content) {
            if (publicKey == null) {
                throw new RuntimeException("public key is null.");
            }
            try {
                Signature signature = Signature.getInstance("SHA1withECDSA", "BC");
                signature.initVerify(publicKey);
                signature.update(content);
                return signature.verify(sign);
            } catch (Exception e) {
                logger.error("ecc verify failed.", e);
            }
            return false;
        }
    }
    
    자바 에서 자주 사용 하 는 암호 화 알고리즘 을 정리 하 는 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 자바 암호 화 알고리즘 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 바 랍 니 다!

    좋은 웹페이지 즐겨찾기