现在项目里面有一个需求,本项目里面下载的视频和文档都不允许通过其他的播放器播放,在培训机构里面这样的需求很多。防止有人交一份钱,把所有的课件就拷给了别人。这样的事情培训机构肯定是不愿意的。现在我项目里面也出了这么个需求。下面介绍一下我的实现。

思路:

首先下载文件,这个就不说了,java代码写个下载管理器。

下载完成后存储文件的时候不是直接存储,要加密存储,加密方法是将文件的每个字节与这个字节在流中的下标做异或运算。

在我们项目里面播放的时候要解密,方法也是将文件的每个字节与这个字节在流中的下标做异或运算。两次异或得到的就是没有加密的值。

  1. /**
  2. * 加密解密管理类
  3. *
  4. * 加密算法 : 将文件的数据流的每个字节与该字节的下标异或.
  5. * 解密算法 : 已经加密的文件再执行一次对文件的数据流的每个字节与该字节的下标异或
  6. *
  7. * @author Administrator
  8. *
  9. */
  10. public class FileEnDecryptManager {
  11. private FileEnDecryptManager() {
  12. }
  13. private static FileEnDecryptManager instance = null;
  14. public static FileEnDecryptManager getInstance() {
  15. synchronized (FileEnDecryptManager.class) {
  16. if (instance == null)
  17. instance = new FileEnDecryptManager();
  18. }
  19. return instance;
  20. }
  21. /**
  22. * 记录上次解密过的文件名
  23. */
  24. private final String LastDecryptFile = Framework
  25. .getModule(DownloadModule.class).getDownloadDir().getAbsolutePath()
  26. + "/LastDecryptFilename.ttt";
  27. /**
  28. * LastDecryptFilename.ttt 文件是否被清空
  29. */
  30. private boolean isClear = false;
  31. /**
  32. * 加密入口
  33. *
  34. * @param fileUrl
  35. *            文件绝对路径
  36. * @return
  37. */
  38. public boolean InitEncrypt(String fileUrl) {
  39. encrypt(fileUrl);
  40. return true;
  41. }
  42. private final int REVERSE_LENGTH = 56;
  43. /**
  44. * 加解密
  45. *
  46. * @param strFile
  47. *            源文件绝对路径
  48. * @return
  49. */
  50. private boolean encrypt(String strFile) {
  51. int len = REVERSE_LENGTH;
  52. try {
  53. File f = new File(strFile);
  54. RandomAccessFile raf = new RandomAccessFile(f, "rw");
  55. long totalLen = raf.length();
  56. if (totalLen < REVERSE_LENGTH)
  57. len = (int) totalLen;
  58. FileChannel channel = raf.getChannel();
  59. MappedByteBuffer buffer = channel.map(
  60. FileChannel.MapMode.READ_WRITE, 0, REVERSE_LENGTH);
  61. byte tmp;
  62. for (int i = 0; i < len; ++i) {
  63. byte rawByte = buffer.get(i);
  64. tmp = (byte) (rawByte ^ i);
  65. buffer.put(i, tmp);
  66. }
  67. buffer.force();
  68. buffer.clear();
  69. channel.close();
  70. raf.close();
  71. return true;
  72. } catch (Exception e) {
  73. e.printStackTrace();
  74. return false;
  75. }
  76. }
  77. /**
  78. * 解密入口
  79. *
  80. * @param fileUrl
  81. *            源文件绝对路径
  82. */
  83. public void Initdecrypt(String fileUrl) {
  84. try {
  85. if (isDecripted(fileUrl)) {
  86. decrypt(fileUrl);
  87. }
  88. } catch (Exception e) {
  89. e.printStackTrace();
  90. }
  91. }
  92. private void decrypt(String fileUrl) {
  93. encrypt(fileUrl);
  94. }
  95. /**
  96. * fileName 文件是否已经解密了
  97. *
  98. * @param fileName
  99. * @return
  100. * @throws IOException
  101. */
  102. private boolean isDecripted(String fileName) throws IOException {
  103. // 上次加密的文件
  104. File lastDecryptFile = new File(LastDecryptFile);
  105. if (lastDecryptFile.exists() && isClear == false) {
  106. String lastDecryptfilepath = getLastDecryptFilePath(LastDecryptFile);
  107. if (lastDecryptfilepath != null
  108. && lastDecryptfilepath.equals(fileName)) {
  109. return false;
  110. } else {
  111. clear();
  112. }
  113. }
  114. StringBufferWrite(fileName);
  115. return true;
  116. }
  117. /**
  118. * 将需要加密的文件绝对路径写入LastDecryptFile
  119. *
  120. * @param filePath
  121. *            需要加密的文件绝对路径
  122. * @param content
  123. * @throws IOException
  124. */
  125. private void StringBufferWrite(String filePath) throws IOException {
  126. File lastDecryptFile = new File(LastDecryptFile);
  127. if (!lastDecryptFile.exists())
  128. lastDecryptFile.createNewFile();
  129. FileOutputStream out = new FileOutputStream(lastDecryptFile, true);
  130. StringBuffer sb = new StringBuffer();
  131. sb.append(filePath);
  132. out.write(sb.toString().getBytes("utf-8"));
  133. out.close();
  134. }
  135. /**
  136. * 清空加密记录
  137. */
  138. public synchronized void clear() {
  139. isClear = true;
  140. File decryptTempFile = new File(LastDecryptFile);
  141. if (decryptTempFile.exists()) {
  142. try {
  143. String fileName = getLastDecryptFilePath(LastDecryptFile);
  144. decrypt(fileName);
  145. new File(LastDecryptFile).delete();
  146. } catch (IOException e) {
  147. e.printStackTrace();
  148. }
  149. }
  150. isClear = false;
  151. }
  152. /**
  153. * 从LastDecryptFile中读取记录
  154. *
  155. * @param filePath
  156. * @return
  157. * @throws IOException
  158. */
  159. private String getLastDecryptFilePath(String filePath) throws IOException {
  160. BufferedReader br = new BufferedReader(new FileReader(filePath));
  161. String str = br.readLine();
  162. br.close();
  163. return str;
  164. }
  165. }

代码就是这么多,都有注释。以后再有这种需求可以直接用。

android 中文件加密 解密 算法实战的更多相关文章

  1. Android中文件加密和解密的实现

    最近项目中需要用到加解密功能,言外之意就是不想让人家在反编译后通过不走心就能获取文件里一些看似有用的信息,但考虑到加解密的简单实现,这里并不使用AES或DES加解密 为了对android中assets ...

  2. 转 node.js和 android中java加密解密一致性问题;

    原文地址,请大家去原文博客了解; http://blog.csdn.net/linminqin/article/details/19972751 我保留一份,防止删除: var crypto = re ...

  3. N个整数(数的大小为0-255)的序列,把它们加密为K个整数(数的大小为0-255).再将K个整数顺序随机打乱,使得可以从这乱序的K个整数中解码出原序列。设计加密解密算法,且要求K<=15*N.

    N个整数(数的大小为0-255)的序列,把它们加密为K个整数(数的大小为0-255).再将K个整数顺序随机打乱,使得可以从这乱序的K个整数中解码出原序列.设计加密解密算法,且要求K<=15*N. ...

  4. 兼容javascript和C#的RSA加密解密算法,对web提交的数据进行加密传输

    Web应用中往往涉及到敏感的数据,由于HTTP协议以明文的形式与服务器进行交互,因此可以通过截获请求的数据包进行分析来盗取有用的信息.虽然https可以对传输的数据进行加密,但是必须要申请证书(一般都 ...

  5. 2019-2-20C#开发中常用加密解密方法解析

    C#开发中常用加密解密方法解析 一.MD5加密算法 我想这是大家都常听过的算法,可能也用的比较多.那么什么是MD5算法呢?MD5全称是 message-digest algorithm 5[|ˈmes ...

  6. Android逆向之旅---Android中锁屏密码算法解析以及破解方案

    一.前言 最近玩王者荣耀,下载了一个辅助样本,结果被锁机了,当然破解它很简单,这个后面会详细分析这个样本,但是因为这个样本引发出的欲望就是解析Android中锁屏密码算法,然后用一种高效的方式制作锁机 ...

  7. 【转】C#中RSA加密解密和签名与验证的实现

    [转]C#中RSA加密解密和签名与验证的实现 RSA加密算法是一种非对称加密算法.在公钥加密标准和电子商业中RSA被广泛使用.RSA是1977年由罗纳德•李维斯特(Ron Rivest).阿迪•萨莫尔 ...

  8. .Net中的加密解密

    返回博客列表 转 .Net中的加密解密 李朝强 发布时间: 2015/11/23 12:55 阅读: 33 收藏: 3 点赞: 0 评论: 0 在一些比较重要的应用场景中,通过网络传递数据需要进行加密 ...

  9. RC4加密解密算法

    RC4相对是速度快.安全性高的加密算法.在实际应用中,我们可以对安全系数要求高的文本进行多重加密,这样破解就有一定困难了.如下测试给出了先用RC4加密,然后再次用BASE64编码,这样双重锁定,保证数 ...

随机推荐

  1. Jdbc 事务

    package com.j1; import java.sql.Connection; import java.sql.SQLException; import com.mysql.jdbc.Prep ...

  2. 广播接收者 BroadcastReceiver 示例-1

    广播机制概述 Android广播分为两个方面:广播发送者和广播接收者,通常情况下,BroadcastReceiver指的就是广播接收者.广播作为Android组件间的通信方式,可以使用的场景如下: 1 ...

  3. less样式表

    LESS是一种由Alexis Sellier设计的动态层叠样式表语言.受Sass所影响,同时也影响了Sass的新语法:SCSS.[2]  LESS是开源的,其第一个版本由Ruby写成,但在后续的版本当 ...

  4. div与span

    div与span的区别: div标签属于块级元素,span标签属于行内元素,使用对比效果如下: <!DOCTYPE html> <html> <head lang=&qu ...

  5. 使用ICallbackEventHandler接口更高效实现Ajax

    使用ICallbackEventHandler接口可以方便地高效地实现Ajax功能 1.处理页面需实现ICallbackEventHandler接口,此接口有两个方法 a.GetCallbackRes ...

  6. (转)jQuery.extend 函数详解

    Jquery的扩展方法extend是我们在写插件的过程中常用的方法,该方法有一些重载原型,在此,我们一起去了解了解       JQuery的extend扩展方法: Jquery的扩展方法extend ...

  7. AngularJs练习Demo14自定义服务

    @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport&quo ...

  8. partial修饰符,可以让同类命名空间下出现重名

    public partial class Person { } public partial class Person { } partial修饰符,可以让同类命名空间下出现重名,两个类其实是一个类, ...

  9. 如何用正则将多个空格看成一个空格结合spllit()方法将文本数据入库

    关键的代码和正则表达式在这里 while((line=br.readLine())!=null) { String[] data=new String[4]; data=line.split(&quo ...

  10. 工作中遇到的浏览器差别(就不叫IE6bug了)

    1.根据ie版本写css <!--[if lt IE 8]> <style> .cntContainer{margin-top: -1px;} </style> & ...