안 드 로 이 드 보안 보호 암호 화 알고리즘

요약
개발 자 나 기업 들 은우리 회사 의 app,데이터 양 이 적 으 면 그 해커 가 배 불리 먹고 할 일이 없어 서 풀 수 있 을 거 야.알 리 페 이도 아니 고 다른 사용자 들 이 많은 애플 리 케 이 션 도 있 습 니 다.그렇게 생각한다 면 근시안 적 이 라 고 할 수 밖 에 없다.
Android 에서 자주 사용 하 는 암호 화 알고리즘
암호 화 된 내용 을 복원 할 수 있 는 지 여 부 는 역 암호 화 와 비 역 암호 화 로 나 눌 수 있다.
비 역 암호 화:즉 암호 화 된 데 이 터 는 원래 의 데이터 로 복원 할 수 없다 는 것 이다.예 를 들 어 MD5 암호 화 는 비밀 번 호 를 암호 화 합 니 다.123456 암호 화 된 후에 afabsbfbabf 437 hffbbff 73(결 과 는 반드시 이것 이 아니 라 예 를 들 어)이 됩 니 다.즉,암호 화 된 결과 afabsbfbabf 437 hfbbff 73 은 123456 이라는 값 을 복호화 할 수 없습니다.
가 역 암호 화:가 역 암호 화 는 공개 키 와 비밀 키 가 있 고 공개 키 를 통 해 데 이 터 를 암호 화하 고 비밀 키 를 통 해 복호화 합 니 다.대표:RSA,AES.
대칭 암호 화 와 비대 칭 암호 화:역 암호 화 는 사용 복호화 에 따라 같은 키 를 사용 하 는 지 여부 에 따라 대칭 암호 화(복호화 와 같은 키 사용)와 비대 칭 암호 화(복호화 키 분리)로 나 뉜 다.
MD5
MD5 의 특징:
1.압축성:임의의 길이 의 데이터 로 계 산 된 MD5 값 의 길 이 는 모두 고정 되 어 있 습 니 다.
2.계산 용이 성:원시 데이터 에서 MD5 값 을 계산 하 는 것 은 매우 쉽다.
3.수정 저항 성:데이터 가 조금 만 바 뀌 면 얻 는 MD5 의 차이 가 매우 크다.
4.강 한 충돌 저항 성:원래 데이터 에서 계 산 된 MD5 는 같은 MD5 를 찾 으 려 면 매우 어렵다.
MD5 의 응용 장면:
1.일치 성 검증(예 를 들 어 어떤 파일 을 다운로드 하면 파일 다운로드 가 완료 되 었 는 지 모 르 고 MD5 로 검증 할 수 있 습 니 다.암호 화 된 파일 은 시간 이 오래 걸 립 니 다.하위 스 레 드 에 넣 어야 합 니 다)
2.비밀번호 의 저장(로그 인 등록 등 계 정 비밀 번 호 는 sp 에 저장 되 고 계 정 비밀번호 의 MD5 값 에 바로 저장 하면 됩 니 다.이렇게 하면 서버 권한 자가 이 비밀 번 호 를 아 는 것 을 피 할 수 있다)
MD5 의 간단 한 사용
MD5 도구 클래스 를 먼저 작성 합 니 다.

package com.example.huangjialin.md5test;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class Utils {

    public static String md5(String content) {
        byte[] hash = null;
        try {
            hash = MessageDigest.getInstance("MD5").digest(content.getBytes("UTF-8"));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        StringBuilder stringBuilder = new StringBuilder(hash.length * 2);
        for (byte b: hash) {
            if ((b & 0xFF) < 0x10){
                stringBuilder.append("0");

            }
            stringBuilder.append(Integer.toHexString(b & 0xFF));

        }
        return stringBuilder.toString();
    }

}
간단하게 설명 하 자 면 먼저 Message Digest.getInstance("MD5")를 통 해 Message Digest 클래스 를 얻 을 수 있 습 니 다.이 클래스 는 자바 가 자체 적 으로 가지 고 있 는 암호 화 클래스 입 니 다.그리고 digest()방법 을 호출 하여 암호 화 된 바이트 그룹 을 얻 을 수 있 습 니 다.이 방법 이 들 어 오 는 매개 변 수 는 by te[]input 이기 때문에 문자열 을 by te[]로 바 꿔 야 합 니 다.암호 화 된 바이트 배열 을 받 은 후 16 금 지 된 문자열 로 바 꾸 고 연결 하면 됩 니 다.
그리고 직접 호출:

/**
* MD5  
*/
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        String md5_123456abc = Utils.md5("123456abc");
        String md5_huangjialin = Utils.md5("huangjialin");
        Log.i("huangjialin","    md5_123456abc   MD5  :    " + md5_123456abc);
        Log.i("huangjialin","    md5_huangjialin   MD5  :   " + md5_huangjialin);
    }
});
얻 은 결과:
09-20 15:33:12.208 7352-7352/com.example.huangjialin.md5test I/huangjialin:     md5_123456 abc 가 계산 한 MD5 값 은:    df10ef8509dc176d733d59549e7dbfaf
09-20 15:33:12.208 7352-7352/com.example.huangjialin.md5test I/huangjialin:     md5_huangjialin 이 계산 한 MD5 값 은:   08e768954478c8669619d7d087db0070
로그 출력 로 그 는 Log.i()와 같은 여러 가지 가 있 습 니 다.Log.d()등등.그러나 현재 일부 휴대 전화 업 체 들 은 등급 이 낮은 로 그 를 직접 차단 하기 때문에 일부 로 그 는 일부 휴대 전화 에서 볼 수 있 고 일부 휴대 전 화 는 보지 못 했다.해결 방법 은 수출 등급 이 높 은 것 으로 바 꾸 는 것 이다.
RSA
RSA 는 현재 비교적 유행 하 는 비대 칭 암호 화 입 니 다.키(공개 키 와 비밀 키)의 공개 키 를 암호 화하 고 비밀 키 를 복호화 해 야 합 니 다.
RSA 의 암호 화 원리
1.무 작위 로 두 개의 큰 질 수 P 와 Q 를 선택 하고 P 는 Q 와 같 지 않 으 며 결 과 를 계산 합 니 다.N=P*Q;
2.1 보다 크 고 N 보다 작은 자연수 E 를 선택 하면 E 는 반드시(P-1)*(Q-1)와 호소해 야 합 니 다.
3.공식 으로 D:D*E=mod(P-1)*(Q-1)를 계산한다.
4.P 와 Q 를 소각 합 니 다.
최종 적 으로 얻 은 N,E 는 공개 키 이 고 D 는 비밀 키 입 니 다.
RSA 복호화 절차
1.갑 은 키 쌍 을 생 성 합 니 다(공개 키 와 비밀 키,공개 키 는 데 이 터 를 암호 화하 고 비밀 키 는 스스로 보존 하 며 데 이 터 를 복호화 합 니 다)
2.갑 은 비밀 키 로 데 이 터 를 암호 화한 다음 에 비밀 키 로 암호 화 된 데 이 터 를 서명 하고 이 를 을 에 게 방송한다.을 은 공개 키 를 사용 하고 서명 을 통 해 복호화 데이터 가 유효한 지 검증 한다.만약 에 유효 하 다 면 공개 키 를 사용 하여 데 이 터 를 복호화 한다.
3.을 은 공개 키 로 데 이 터 를 암호 화하 고 갑 에 게 암호 화 된 데 이 터 를 보 내 면 갑 또는 암호 화 된 데 이 터 를 통 해 비밀 키 로 복호화 할 수 있다.
RSA 사용 필드
프로젝트 중의 일부 민감 한 데이터,예 를 들 어 신분증 번호,은행 카드 등 관련 정 보 는 암호 화 를 통 해 서버 에 전 달 될 수 있 고 서버 는 비밀 키 를 사용 하여 복호화 할 수 있다.
RSA 키 쌍 생 성
RSA 키 쌍 생 성 방식 은 두 가지 가 있 습 니 다.

/*
         KeyPairGenerator ,         
    */
    byte[] publicKeyByte;
    byte[] prvateKtyByte;

    public void getKey() {
        try {
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(“RSA”);//KeyPairGenerator  java             。
            keyPairGenerator.initialize(1024); //        
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            PrivateKey privateKey = keyPair.getPrivate();//    
            PublicKey publicKey = keyPair.getPublic();//    
            prvateKtyByte = privateKey.getEncoded();//         
            publicKeyByte = publicKey.getEncoded(); //         

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }
물론 위 에서 키 쌍 을 만 드 는 방식 은 프로젝트 에서 거의 사용 되 지 않 습 니 다.많이 사용 하 는 것 은 두 번 째 방법 입 니 다.
두 번 째 는 OpenSSL 도 구 를 통 해 키 쌍 을 만 드 는 것 입 니 다.
키 쌍 을 만 드 는 방식 은 OpenSSL 을 설치 해 야 합 니 다.여 기 는 구체 적 으로 어떻게 설치 하 는 지 는 말 하지 않 겠 습 니 다.키 쌍 을 만 드 는 데 필요 한 명령 을 간단히 말씀 드 리 겠 습 니 다.
명령 을 사용 하여 비밀 키 생 성:
genrsa -out rsa_private_key.pem 1024
이 명령 은 openssl 에 무 작위 로 비밀 키 를 만 드 는 것 입 니 다.길 이 는 1024 입 니 다.
명령 을 사용 하여 공개 키 생 성:
rsa -in rsa_private_key.pem -out rsa_public_key.pem -pubout
명령 이 성공 하면 openSSL 의 bin 디 렉 터 리 에서 공개 키 와 비밀 키 를 생 성 한 다음 에 암호 화 와 복호화 할 수 있 습 니 다.
암호 화

/**
     *   
     */


    @RequiresApi(api = Build.VERSION_CODES.O)
    public byte[] encryption(String content) {
        byte[] result = null;
        try {
            Cipher cipher = Cipher.getInstance("RSA");
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicKeyByte);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            result = cipher.doFinal(content.getBytes());
            Log.i("huangjialin", "---->  " + Base64.getEncoder().encodeToString(result));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        }
        return result;
    }
복호화

/**
     *   
     */

    @RequiresApi(api = Build.VERSION_CODES.O)

    public void decryption() {

        Cipher cipher = null;
        try {
            cipher = Cipher.getInstance("RSA");
            //      PKCS8EncodedKeySpec   
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(prvateKtyByte);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            //    
            PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            //String content = "123456";
            byte[] input = encryption("123456");
            byte[] result = cipher.doFinal(input);
            Log.i("huangjialin", "--  -->  " + new String(result));
            //Assert.assertTrue(content.equals(new String(result)));


        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        }


    }
물론 위의 코드 는 제 가 테스트 용 으로 쓴 것 입 니 다.진정한 프로젝트 에 서 는 포장 을 잘 해서 도구 류 로 만들어 서 호출 해 야 합 니 다.
AES
AES 는 대칭 암호 화 입 니 다.즉,AES 를 사용 하여 암호 화 와 복호화 를 하 는데 그들 이 사용 하 는 키 는 모두 같 습 니 다.AES 암호 화 알고리즘 은 암호학 에서 고급 암호 화 기준 으로 Rijndael 암호 화 법 이 라 고도 부 르 며 미국 연방정부 가 사용 하 는 블록 암호 화 기준 이다.이 표준 은 원래 의 DES 를 대체 하 는 데 사용 되 었 으 며,이미 다방면으로 분석 되 어 사용 되 었 다.동시에 AES 의 알고리즘 은 암호 화 강도 가 높 고 실행 효율 이 높다.
AES 사용 필드
1.AES 는 대칭 암호 화 이 고 복호화 도 같은 키 를 사용 하기 때문에 프로젝트 에 민감 한 데 이 터 를 로 컬 에 저장 해 야 합 니 다.AES 키 와 먼저 암호 화 할 수 있 습 니 다.필요 한 것 을 사용 하고 데 이 터 를 꺼 낸 다음 복호화 할 수 있 습 니 다.
2.일부 민감 한 데 이 터 를 암호 화하 여 서버 에 전달 할 수 있 습 니 다.
AES 사용
Android 7.0 이전에 키 를 이렇게 가 져 올 수 있 습 니 다.

private SecretKey generateKey(String seed) throws Exception {
        //        
        KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
        //        
        SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG", "Crypto");

        secureRandom.setSeed(seed.getBytes("UTF-8"));
        keyGenerator.init(128, secureRandom);
        //        
        return keyGenerator.generateKey();
    }
하지만 안 드 로 이 드 7.0 이후 지원 하지 않 아 크 립 토 를 제거 했다.물론 이러한 키 획득 방식 은 7.0 이후 Google 에서 도 해결 방안 을 제 시 했 지만,공식 적 으로 는 이 를 권장 하지 않 습 니 다.구체 적 으로 는 여 기 를 볼 수 있 습 니 다.https://android-developers.googleblog.com/2016/06/security-crypto-provider-deprecated-in.html
공식 적 으로 는 키 를 가 져 오지 않 고 비밀 번 호 를 정의 하 는 다른 방식 을 제시 합 니 다.

package com.example.huangjialin.md5test;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Base64;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public class MainActivity extends AppCompatActivity {
    private EditText edittext;
    private Button button, jiami, jiemi;
    private TextView textView;
    private SecretKey secretKey;
    private byte[] bytes;
    private String content = "huangjialin,        ";
    String password = "huangji   ";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        edittext = findViewById(R.id.edittext);
        button = findViewById(R.id.button);
        textView = findViewById(R.id.textview);
        jiami = findViewById(R.id.jiami);
        jiemi = findViewById(R.id.jiemi);

        Log.i("huagjialin", "--     -- > " + content);

        /**
         *     
         */
       /* button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    secretKey = generateKey("huangjiain");
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
        });*/


        /**
         *   
         */

        jiami.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    bytes = encrypt(content, password);
                    String str = new String(bytes);
                    Log.i("huagjialin", "--      -- > " + Base64.decode(str,Base64.DEFAULT));
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
        });

        /**
         *   
         */

        jiemi.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    byte[] by = decrypt(bytes, password);
                    String string = new String(by);
                    Log.i("huagjialin", "--      -- > " + string);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });


    }

    /**
     *        
     */
    private byte[] encrypt(String content, String password) throws Exception {
        //   AES  
        SecretKeySpec key = new SecretKeySpec(password.getBytes(), "AES/CBC/PKCS5PADDING");
        //      
        Cipher cipher = Cipher.getInstance("AES");
        //       
        cipher.init(Cipher.ENCRYPT_MODE, key);
        //   
        return cipher.doFinal(content.getBytes("UTF-8"));
    }


    /**
     *   
     */
    private byte[] decrypt(byte[] content, String password) throws Exception {
        //   AES  
        SecretKeySpec key = new SecretKeySpec(password.getBytes(), "AES/CBC/PKCS5PADDING");
        //      
        Cipher cipher = Cipher.getInstance("AES");
        //       
        cipher.init(Cipher.DECRYPT_MODE, key);
        //   
        return cipher.doFinal(content);
    }

}
09-20 21:12:36.394 15933-15933/com.example.huangjialin.md5test I/huagjialin:암호 화 된 데이터-->huangjialin,암호 화 할 데이터 입 니 다.
09-20 21:12:39.561 15933-15933/com.example.huangjialin.md5test I/huagjialin:--암호 화 된 데이터-->[B@d62495e
09-20 21:12:41.829 15933-15933/com.example.huangjialin.md5test I/huagjialin:-복호화 후의 데이터-->huangjialin,암호 화 할 데이터 입 니 다.
이상 은 우리 가 비교적 자주 사용 하 는 몇 가지 암호 화 된 내용 이다.
이상 은 안 드 로 이 드 안전 보호의 암호 화 알고리즘 에 대한 상세 한 내용 입 니 다.안 드 로 이 드 안전 보호의 암호 화 알고리즘 에 관 한 자 료 는 저희 의 다른 관련 글 을 주목 하 십시오!

좋은 웹페이지 즐겨찾기