Android 加密/解密音频文件(AES) Android java.security.NoSuchProviderException: no such provider: Crypto

原文地址:https://blog.csdn.net/u012964281/article/details/41787857

加密过程:以byte[]形式读取SD卡上准备好的测试音频文件,使用AES加密算法加密byte[],再保存覆盖原音频文件,此时加密后的音频文件无法被播放。解密和加密过程原理一样,解密保存后的音频文件可以被播放。


代码:

VoiceEncryptionActivity.java

[java]  view plain  copy
  1. package com.example.voiceencryption;  
  2.   
  3. import java.io.File;  
  4. import java.io.FileInputStream;  
  5. import java.io.FileNotFoundException;  
  6. import java.io.FileOutputStream;  
  7. import java.io.IOException;  
  8.   
  9. import android.app.Activity;  
  10. import android.media.MediaPlayer;  
  11. import android.os.Bundle;  
  12. import android.os.Environment;  
  13. import android.util.Log;  
  14. import android.view.View;  
  15. import android.view.View.OnClickListener;  
  16. import android.widget.Button;  
  17. import android.widget.Toast;  
  18.   
  19. public class VoiceEncryptionActivity extends Activity implements  
  20.         OnClickListener {  
  21.     private static final String TAG = "VoiceEncryptionActivity";  
  22.     private static final String seed = "guess"// 种子  
  23.     private MediaPlayer mPlayer;  
  24.     private Button mPlayButton;  
  25.     private Button mEncryptionButton;  
  26.     private Button mDecryptionButton;  
  27.     private File sdCard = Environment.getExternalStorageDirectory();  
  28.     private File oldFile = new File(sdCard, "recording_old.3gpp");  
  29.     // 音频文件的路径,在res\raw\recording_old.3gpp中找到音频文件,再放到外部存储的根目录下。用于测试  
  30.     private FileInputStream fis = null;  
  31.     private FileOutputStream fos = null;  
  32.   
  33.     @Override  
  34.     protected void onCreate(Bundle savedInstanceState) {  
  35.         super.onCreate(savedInstanceState);  
  36.         setContentView(R.layout.activity_voice_encryption);  
  37.         mPlayButton = (Button) findViewById(R.id.playButton);  
  38.         mPlayButton.setOnClickListener(this);  
  39.         mEncryptionButton = (Button) findViewById(R.id.encryptionButton);  
  40.         mEncryptionButton.setOnClickListener(this);  
  41.         mDecryptionButton = (Button) findViewById(R.id.decryptionButton);  
  42.         mDecryptionButton.setOnClickListener(this);  
  43.   
  44.     }  
  45.   
  46.     @SuppressWarnings("static-access")  
  47.     @Override  
  48.     public void onClick(View v) {  
  49.         switch (v.getId()) {  
  50.         case R.id.playButton:  
  51.             if (mPlayer != null) {  
  52.                 mPlayer.release();  
  53.                 mPlayer = null;  
  54.             }  
  55.             // mPlayer = MediaPlayer.create(this, R.raw.recording_old);  
  56.             boolean isSuccess = true;  
  57.             try {  
  58.                 fis = new FileInputStream(oldFile);  
  59.                 mPlayer = new MediaPlayer();  
  60.                 mPlayer.setDataSource(fis.getFD());  
  61.                 mPlayer.prepare(); // 去掉会出错  
  62.                 mPlayer.start();  
  63.             } catch (FileNotFoundException e) {  
  64.                 isSuccess = false;  
  65.                 e.printStackTrace();  
  66.             } catch (IllegalArgumentException e) {  
  67.                 isSuccess = false;  
  68.                 e.printStackTrace();  
  69.             } catch (IllegalStateException e) {  
  70.                 isSuccess = false;  
  71.                 e.printStackTrace();  
  72.             } catch (IOException e) {  
  73.                 isSuccess = false;  
  74.                 e.printStackTrace();  
  75.             } finally {  
  76.                 try {  
  77.                     fis.close();  
  78.                 } catch (IOException e) {  
  79.                     e.printStackTrace();  
  80.                 }  
  81.             }  
  82.             if (!isSuccess)  
  83.                 Toast.makeText(this"播放失败", Toast.LENGTH_SHORT).show();  
  84.             break;  
  85.   
  86.         case R.id.encryptionButton:  
  87.             // 加密保存  
  88.             isSuccess = true;  
  89.             try {  
  90.                 fis = new FileInputStream(oldFile);  
  91.                 byte[] oldByte = new byte[(int) oldFile.length()];  
  92.                 fis.read(oldByte); // 读取  
  93.                 byte[] newByte = AESUtils.encryptVoice(seed, oldByte);  
  94.                 // 加密  
  95.                 fos = new FileOutputStream(oldFile);  
  96.                 fos.write(newByte);  
  97.   
  98.             } catch (FileNotFoundException e) {  
  99.                 isSuccess = false;  
  100.                 e.printStackTrace();  
  101.             } catch (IOException e) {  
  102.                 isSuccess = false;  
  103.                 e.printStackTrace();  
  104.             } catch (Exception e) {  
  105.                 isSuccess = false;  
  106.                 e.printStackTrace();  
  107.             } finally {  
  108.                 try {  
  109.                     fis.close();  
  110.                     fos.close();  
  111.                 } catch (IOException e) {  
  112.                     e.printStackTrace();  
  113.                 }  
  114.             }  
  115.             if (isSuccess)  
  116.                 Toast.makeText(this"加密成功", Toast.LENGTH_SHORT).show();  
  117.             else  
  118.                 Toast.makeText(this"加密失败", Toast.LENGTH_SHORT).show();  
  119.   
  120.             Log.i(TAG, "保存成功");  
  121.             break;  
  122.   
  123.         case R.id.decryptionButton:  
  124.             // 解密保存  
  125.             isSuccess = true;  
  126.             byte[] oldByte = new byte[(int) oldFile.length()];  
  127.             try {  
  128.                 fis = new FileInputStream(oldFile);  
  129.                 fis.read(oldByte);  
  130.                 byte[] newByte = AESUtils.decryptVoice(seed, oldByte);  
  131.                 // 解密  
  132.                 fos = new FileOutputStream(oldFile);  
  133.                 fos.write(newByte);  
  134.   
  135.             } catch (FileNotFoundException e) {  
  136.                 isSuccess = false;  
  137.                 e.printStackTrace();  
  138.             } catch (IOException e) {  
  139.                 isSuccess = false;  
  140.                 e.printStackTrace();  
  141.             } catch (Exception e) {  
  142.                 isSuccess = false;  
  143.                 e.printStackTrace();  
  144.             }  
  145.             try {  
  146.                 fis.close();  
  147.                 fos.close();  
  148.             } catch (IOException e) {  
  149.                 e.printStackTrace();  
  150.             }  
  151.             if (isSuccess)  
  152.                 Toast.makeText(this"解密成功", Toast.LENGTH_SHORT).show();  
  153.             else  
  154.                 Toast.makeText(this"解密失败", Toast.LENGTH_SHORT).show();  
  155.             break;  
  156.   
  157.         default:  
  158.             break;  
  159.         }  
  160.   
  161.     }  
  162. }  

AESUtils.java

[java]  view plain  copy
  1. package com.example.voiceencryption;  
  2.   
  3. import java.security.SecureRandom;  
  4.   
  5. import javax.crypto.Cipher;  
  6. import javax.crypto.KeyGenerator;  
  7. import javax.crypto.SecretKey;  
  8. import javax.crypto.spec.IvParameterSpec;  
  9. import javax.crypto.spec.SecretKeySpec;  
  10.   
  11. public class AESUtils {  
  12.     public static byte[] encryptVoice(String seed, byte[] clearbyte)  
  13.             throws Exception {  
  14.         byte[] rawKey = getRawKey(seed.getBytes());  
  15.         byte[] result = encrypt(rawKey, clearbyte);  
  16.         return result;  
  17.     }  
  18.   
  19.     public static byte[] decryptVoice(String seed, byte[] encrypted)  
  20.             throws Exception {  
  21.         byte[] rawKey = getRawKey(seed.getBytes());  
  22.         byte[] result = decrypt(rawKey, encrypted);  
  23.         return result;  
  24.     }  
  25.   
  26.     private static byte[] getRawKey(byte[] seed) throws Exception {  
  27.         KeyGenerator kgen = KeyGenerator.getInstance("AES");  
  28.         SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", new CryptoProvider());  
  29.         sr.setSeed(seed);  
  30.         kgen.init(128, sr);  
  31.         SecretKey skey = kgen.generateKey();  
  32.         byte[] raw = skey.getEncoded();  
  33.         return raw;  
  34.     }  
  35.   
  36.     private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {  
  37.         SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");  
  38.         Cipher cipher = Cipher.getInstance("AES");  
  39.         cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(  
  40.                 new byte[cipher.getBlockSize()]));  
  41.         byte[] encrypted = cipher.doFinal(clear);  
  42.         return encrypted;  
  43.     }  
  44.   
  45.     private static byte[] decrypt(byte[] raw, byte[] encrypted)  
  46.             throws Exception {  
  47.         SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");  
  48.         Cipher cipher = Cipher.getInstance("AES");  
  49.         cipher.init(Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec(  
  50.                 new byte[cipher.getBlockSize()]));  
  51.         byte[] decrypted = cipher.doFinal(encrypted);  
  52.         return decrypted;  
  53.     }  
  54. }  

CryptoProvider.java

import java.security.Provider;

/**
 * Created by xxx on 2018/6/1.
 */

public class CryptoProvider extends Provider {

    /**
     * Creates a Provider and puts parameters
     */
    public CryptoProvider() {
        super("Crypto", 1.0, "HARMONY (SHA1 digest; SecureRandom; SHA1withDSA signature)");
        put("SecureRandom.SHA1PRNG",
                "org.apache.harmony.security.provider.crypto.SHA1PRNG_SecureRandomImpl");
        put("SecureRandom.SHA1PRNG ImplementedIn", "Software");
    }
}

原方法存在兼容性问题,已修改好,采用方式如下文:

Android java.security.NoSuchProviderException: no such provider: Crypto

https://blog.csdn.net/dodod2012/article/details/80540926

源码:http://download.csdn.net/detail/u012964281/8233079

猜你喜欢

转载自blog.csdn.net/dodod2012/article/details/80770603