Androidでよく使われるデータ暗号化方式コードの詳細

11710 ワード

前言
Androidでは、ローカルログインパスワード暗号化、ネットワーク転送データ暗号化など、データ暗号化に使用する場合が多い.Androidでは一般的な暗号化方式は以下の通りです.
AES暗号化RSA非対称暗号化MD 5暗号化アルゴリズムも暗号化する
もちろん他の方法もありますが、ここでは、上記の4つの暗号化アルゴリズムの使用方法について説明します.
または暗号化アルゴリズム
暗号化とは何ですか?
あるいは暗号化は、あるバイトに対しても演算も行い、例えばバイトA^K=Vであり、これは暗号化プロセスである.V^Kで得られた結果がA,すなわちV^K=Aである場合,これは逆操作プロセスであり,復号プロセスである.
また、操作効率が高いか、もちろん暗号化も比較的簡単な暗号化方式であり、操作にスペースが増加しないか、ソースデータがどれだけ大きいか、暗号化された後もデータがどれだけ大きいか.
サンプルコードは次のとおりです.

/**
   *      ,            ,      ,   
   *  file         ,  zip     
   *
   * @param source        
   * @param det          
   * @param key    key
   */
public static void encryptionFile(File source, File det, int key) {
	FileInputStream fis = null;
	FileOutputStream fos = null;
	try {
		fis = new FileInputStream(source);
		fos = new FileOutputStream(det);
		int size = 2048;
		byte buff[] = new byte[size];
		int count = fis.read(buff);
		/**zip     */
		for (int i = 0; i < count; i++) {
			fos.write(buff[i] ^ key);
		}
		while (true) {
			count = fis.read(buff);
			/**zip     */
			if (count < size) {
				for (int j = 0; j < count; j++) {
					fos.write(buff[j] ^ key);
				}
				break;
			}
			fos.write(buff, 0, count);
		}
		fos.flush();
	}
	catch (IOException e) {
		e.printStackTrace();
	}
	finally {
		try {
			if (fis != null) {
				fis.close();
			}
			if (fos != null) {
				fos.close();
			}
		}
		catch (IOException e) {
			e.printStackTrace();
		}
	}
}
/**
   *      ,         
   *
   * @param source          
   * @param det            
   * @param key      key
   */
private static void encryptionFile(String source, String det, int key) {
	FileInputStream fis = null;
	FileOutputStream fos = null;
	try {
		fis = new FileInputStream(source);
		fos = new FileOutputStream(det);
		int read;
		while ((read = fis.read()) != -1) {
			fos.write(read ^ key);
		}
		fos.flush();
	}
	catch (IOException e) {
		e.printStackTrace();
	}
	finally {
		try {
			if (fis != null) {
				fis.close();
			}
			if (fos != null) {
				fos.close();
			}
		}
		catch (IOException e) {
			e.printStackTrace();
		}
	}
}

zip圧縮パケットのようなファイルの一部を暗号化することで、ヘッダとテールを暗号化することができます.zipヘッダとテールにはファイル圧縮に関する情報が隠されているため、すべて、ヘッダとテールに対しても暗号化アルゴリズムを採用するだけで、zipファイル全体を暗号化することができます.復号しないで加圧しようとすると失敗します.ファイル全体に対しても暗号化アルゴリズムも行うことができるので、復号するときは逆方向のプロセスであり、同じ方法で同じkeyで暗号化されたファイルを復号することができます.もちろん、後で暗号化のセキュリティが考えられるように、安全ではないので、暗号化アルゴリズムは一般的にあまり重要ではないシーンで使用されています.アルゴリズムも速いため、暗号化速度も速い.
AES暗号化アルゴリズム
AES暗号化とは
AES対称暗号化
高度な暗号化規格(英語:Advanced Encryption Standard、略称:AES)は、暗号学ではRijndael暗号化法とも呼ばれ、米連邦政府が採用しているブロック暗号化規格である.この基準は従来のDESの代わりに用いられ,多方面にわたって分析され,世界中で広く用いられている.
AndroidのAES暗号化鍵keyは16/24/32ビットバイトでなければなりません.そうしないと、異常が発生します.
サンプルコード:

private static final String TAG = "EncryptUtils";
private final static int MODE_ENCRYPTION = 1;
private final static int MODE_DECRYPTION = 2;
private final static String AES_KEY = "xjp_12345!^-=42#";
//AES   key,   16 
private static byte[] encryption(int mode, byte[] content, String pwd) {
	try {
		Cipher cipher = Cipher.getInstance("AES/CFB/NoPadding");
		//AES    ,CFB     
		SecretKeySpec keySpec = new SecretKeySpec(pwd.getBytes("UTF-8"), "AES");
		//AES    
		IvParameterSpec ivSpec = new IvParameterSpec(pwd.getBytes("UTF-8"));
		cipher.init(mode == MODE_ENCRYPTION ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE, keySpec, ivSpec);
		return cipher.doFinal(content);
	}
	catch (NoSuchAlgorithmException | NoSuchPaddingException |
	        InvalidKeyException | IllegalBlockSizeException |
	        BadPaddingException | InvalidAlgorithmParameterException e) {
		e.printStackTrace();
		Log.e(TAG, "encryption failed... err: " + e.getMessage());
	}
	catch (Exception e) {
		e.printStackTrace();
		Log.e(TAG, "encryption1 failed ...err: " + e.getMessage());
	}
	return null;
}
/**
   * AES   
   *
   * @param source          
   * @param dest          
   */
public static void encryptByAES(String source, String dest) {
	encryptByAES(MODE_ENCRYPTION, source, dest);
}
public static void encryptByAES(int mode, String source, String dest) {
	Log.i(TAG, "start===encryptByAES");
	FileInputStream fis = null;
	FileOutputStream fos = null;
	try {
		fis = new FileInputStream(source);
		fos = new FileOutputStream(dest);
		int size = 2048;
		byte buff[] = new byte[size];
		byte buffResult[];
		while ((fis.read(buff)) != -1) {
			buffResult = encryption(mode, buff, AES_KEY);
			if (buffResult != null) {
				fos.write(buffResult);
			}
		}
		Log.i(TAG, "end===encryptByAES");
	}
	catch (IOException e) {
		e.printStackTrace();
		Log.e(TAG, "encryptByAES failed err: " + e.getMessage());
	}
	finally {
		try {
			if (fis != null) {
				fis.close();
			}
			if (fos != null) {
				fos.close();
			}
		}
		catch (IOException e) {
			e.printStackTrace();
		}
	}
}
/**
   * AES   
   *
   * @param source          
   * @param dest            
   */
public static void decryptByAES(String source, String dest) {
	encryptByAES(MODE_DECRYPTION, source, dest);
}

AES対称暗号化、復号化は暗号化よりもやや複雑で、セキュリティも暗号化よりも高く、AES暗号化は絶対的なセキュリティではありません.
RSA非対称暗号化
Rsa暗号化とは?
RSAアルゴリズムは最もポピュラーな公開鍵暗号アルゴリズムであり,長さが変化可能な鍵を用いる.RSAは、データ暗号化にもデジタル署名にも使用できる最初のアルゴリズムです.
RSAの安全性は大数分解に依存し、1024ビット未満のNは安全ではないことが証明されている.また、RSAアルゴリズムは大数計算を行うため、RSAが最も速い場合もDESより倍遅く、これはRSAの最大の欠陥であるため、通常は少量のデータまたは暗号化鍵の暗号化にしか使用できないが、RSAは依然として高強度のアルゴリズムである.
コードの例:

/**************************************************
   * 1.   RSA      ?
   * 

* 2. *************************************************/ private final static String RSA = "RSA"; // RSA public final static int DEFAULT_KEY_SIZE = 1024; private final static int DECRYPT_LEN = DEFAULT_KEY_SIZE / 8; // private final static int ENCRYPT_LEN = DECRYPT_LEN - 11; // private static final String DES_CBC_PKCS5PAD = "DES/CBC/PKCS5Padding"; // private final static int MODE_PRIVATE = 1; // private final static int MODE_PUBLIC = 2; // /** * RSA , PublicKey,PrivateKey * * @param keyLength , 512~2048, 1024 * @return KeyPair */ public static KeyPair generateRSAKeyPair(int keyLength) { try { KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); kpg.initialize(keyLength); return kpg.genKeyPair(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return null; } } /** * * * @return PrivateKey * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException */ public static PrivateKey getPrivateKey(String key) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException { byte[] privateKey = Base64.decode(key, Base64.URL_SAFE); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKey); KeyFactory kf = KeyFactory.getInstance(RSA); return kf.generatePrivate(keySpec); } /** * * * @param key * @return PublicKey * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException */ public static PublicKey getPublicKey(String key) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException { byte[] publicKey = Base64.decode(key, Base64.URL_SAFE); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKey); KeyFactory kf = KeyFactory.getInstance(RSA); return kf.generatePublic(keySpec); } /** * * * @param data * @param key * @return * @throws Exception */ public static byte[] encryptByRSA(byte[] data, Key key) throws Exception { // Cipher cipher = Cipher.getInstance(RSA); cipher.init(Cipher.ENCRYPT_MODE, key); return cipher.doFinal(data); } /** * * * @param data * @param key * @return byte[] */ public static byte[] decryptByRSA(byte[] data, Key key) throws Exception { // Cipher cipher = Cipher.getInstance(RSA); cipher.init(Cipher.DECRYPT_MODE, key); return cipher.doFinal(data); } public static void encryptByRSA(String source, String dest, Key key) { rasEncrypt(MODE_ENCRYPTION, source, dest, key); } public static void decryptByRSA(String source, String dest, Key key) { rasEncrypt(MODE_DECRYPTION, source, dest, key); } public static void rasEncrypt(int mode, String source, String dest, Key key) { Log.i(TAG, "start===encryptByRSA mode--->>" + mode); FileInputStream fis = null; FileOutputStream fos = null; try { fis = new FileInputStream(source); fos = new FileOutputStream(dest); int size = mode == MODE_ENCRYPTION ? ENCRYPT_LEN : DECRYPT_LEN; byte buff[] = new byte[size]; byte buffResult[]; while ((fis.read(buff)) != -1) { buffResult = mode == MODE_ENCRYPTION ? encryptByRSA(buff, key) : decryptByRSA(buff, key); if (buffResult != null) { fos.write(buffResult); } } Log.i(TAG, "end===encryptByRSA"); } catch (IOException e) { e.printStackTrace(); Log.e(TAG, "encryptByRSA failed err: " + e.getMessage()); } catch (Exception e) { e.printStackTrace(); } finally { try { if (fis != null) { fis.close(); } if (fos != null) { fos.close(); } } catch (IOException e) { e.printStackTrace(); } } }


MD 5暗号化アルゴリズム:

public String getMD5Code(String info) {
	try {
		MessageDigest md5 = MessageDigest.getInstance("MD5");
		md5.update(info.getBytes("UTF-8"));
		byte[] encryption = md5.digest();
		StringBuffer strBuf = new StringBuffer();
		for (int i = 0; i < encryption.length; i++) {
			if (Integer.toHexString(0xff & encryption[i]).length() == 1) {
				strBuf.append("0").append( 
				            Integer.toHexString(0xff & encryption[i]));
			} else {
				strBuf.append(Integer.toHexString(0xff & encryption[i]));
			}
		}
		return strBuf.toString();
	}
	catch (Exception e) {
		// TODO: handle exception 
		return "";
	}
}

1.AES公開鍵暗号化、秘密鍵復号2.AES暗号化には3時間かかる.AES暗号化するとデータが大きくなります
まとめ
以上、Androidでよく使われるデータ暗号化方式コードの詳細について説明したすべての内容であり、皆さんの役に立つことを願っています.不足点があれば、コメントを歓迎します.友人の皆様のご支援に感謝いたします.