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

思路:

首先下载文件,这个就不说了,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. next数组

    首先看看next数组值的求解方法例如: 模式串 a b a a b c a c next值 0 1 1 2 2 3 1 2               next数组的求解方法是:第一位的next值为0 ...

  2. jquery之遍历展示title

    //遍历展示title {field:'couponsList',title:'优惠劵类型',width:250,align:'center',sortable:true, formatter:fun ...

  3. HQL查询

    HQL ,Hibernate Query Language ,是Hibernate查询语言,不直接操作数据表,而是操作实体类,根据实体类和对应数据表中的映射关系,查找数据. 下面是hql的基本步骤: ...

  4. properties文件的读取

    Demo //声明资源器类 Properties pro=new Properties(); //获取路径 URL url= PropertiesTest.class.getClassLoader() ...

  5. C++中的struct与class继承方式

    代码: #include <iostream> #include <cstdio> using namespace std; //class A{ struct A{ publ ...

  6. jQuery自学笔记(三):jQuery动画效果

    jQuery隐藏和显示: 使用 hide( ) 和 show( ) 方法来隐藏和显示 HTML 元素: 语法: $(selector).hide(speed,callback); $(selector ...

  7. 记录一下最近开发web移动前端的过程

    两个项目 第一个是公司网站的移动端,我所在的公司是做某方面的新闻站的. 所以说页面基本是以一条条的新闻+图文混排为主,顶部有一个自动slider+触屏滑动的功能, 使用的是swipe插件,轻量,简洁非 ...

  8. jquery的.detach()方法

    .detach()就是从DOM中删除所有匹配的元素. 与.remove()方法不同的是, 这个方法不会把匹配的元素从jQuery对象中删除,所有绑定的事件.附加的数据等都会保留下来,因而可以在将来再使 ...

  9. 利用csc.exe 手动编译C#程序

    1. 创建见 cs代码文件 using System; class TestApp{ static void Main() { Console.WriteLine("Test! 1,2,3& ...

  10. 《转》JAVA动态代理(JDK和CGLIB)

    该文章转自:http://www.cnblogs.com/jqyp/archive/2010/08/20/1805041.html JAVA的动态代理 代理模式 代理模式是常用的java设计模式,他的 ...