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

思路:

首先下载文件,这个就不说了,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. Word03-文档中的截图显示不全

    今天写文档时遇到个很蛋疼的问题,在doc文档中复制进去的截图总是显示不全,图片上半部分都被文字遮盖了,折腾半天,最后还是网上找到了答案. 解决方法如下: 将图片所在行的段落行距修改为其它值即可,原来为 ...

  2. 206.反转单列表 Reverse Linked List

    Reverse a singly linked list. 使用栈 public class Solution { public ListNode ReverseList(ListNode head) ...

  3. Chrome: Shockwave Flash isn't responding

    这个问题问 Google 解决得比较快,百度里尽是转载党的东西! 1. 到 chrome://settings/content 找到 Plug-ins 项目 2. 点击 Plug-ins 里的 Exc ...

  4. IDEA 运行 控制台显示一堆乱码,一些问号

    如下: 问题: 配置程序运行参数的时候,配置到了"VM options",应该为配置到"Program arguments",如图:

  5. ios内存详解

    IOS以及Mac os都是基于Unix/linux改造出来的,而在内存管理方面也沿用了Unix/Linux的内存管理机制. 下面主要说的是IOS系统,有很多比较喜欢捣鼓的吧友肯定自己清理过机器的内存, ...

  6. C#多线程实践——锁和线程安全

    锁实现互斥的访问,用于确保在同一时刻只有一个线程可以进入特殊的代码片段,考虑下面的类: class ThreadUnsafe { static int val1, val2; static void ...

  7. IIS上部署网站404错误

    新装的系统上部署.net网站遇到403.404错误,可能原因记录: 1.应用程序池选择错误,一般选择4.0的 2.ASP.NET4.0应用程序池未安装(一般先安装了framework4.0,后安装ii ...

  8. 一个小玩具:Python调用Mysql

    1. ubuntu安装MySQL how to install:$ sudo apt-get install mysql-server$ sudo apt-get install mysql-clie ...

  9. ubuntu openssh-server

    1.   sudo apt-get install openssh-server 2.   sudo service ssh start 3.   sudo service ssh status 4. ...

  10. 用lambda表达式替代 for循环进行批量操作。

    IEnumerable<Rect> rectlist3 = rectlist.Select(rect =>newRect(rect.X + 2000, rect.Y, rect.re ...