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

思路:

首先下载文件,这个就不说了,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. CentOS yum Fatal Error 处理一例

    环境说明 [root@thatsit ~]# cat /etc/redhat-release CentOS Linux release (Core) [root@thatsit ~]# uname - ...

  2. 关于在css里设置图片圆角的问题

    今天做了一个项目,效果图内页的产品图片都是带圆角的,于是前端的做了圆角的效果,div+css是这样的,首先div布局是: <div class="tiandi_item" o ...

  3. Android WifiDirect 学习(三) 一些基础知识和问题

    P2P架构介绍 P2P架构中定义了三个组件,一个设备,两种角色.这三个组件分别是: P2P Device:它是P2P架构中角色的实体,读者可把它当做一个Wi-Fi设备. P2P Group Owner ...

  4. .net ADF 中 Ajax 的调用过程.

    图示是 .net ADF Ajax调用过程的简略过程: 1,2)当页面初始化之后, 浏览器一旦触发回调事件, 脚本函数负责处理回调信息, 并调用 ASP.NET 2.0/3.5 中的 WebForm_ ...

  5. Swift中子类必须包含的构造器和析构器

    import Foundation /* Swift中子类必须包含的构造器 1.Swift允许在父类构造器前添加required关键字, 用于声明所有子类必须包含该required构造器 (如果没有声 ...

  6. jQuery源码分析1

    写在开头: 昨天开始,我决定要认真的看看jQuery的源码,选择1.7.2,源于公司用的这个版本.由于源码比较长,这将会是一个比较持久的过程,我将要利用业余时间,和偶尔上班不算忙的时间来进行.其实原本 ...

  7. 在git bush中如何退出vim编辑器

    写npm的pakege.json文件的files配置时,如果有不想包含的文件,那就要创建.npmignore文件排除,但windows系统又不允许创建以点开头命名的文件,咋办? 这时候就要用到linu ...

  8. jquery1.9学习笔记 之层级选择器(三)

    下一个相邻选择器(“prev + next”) 描述:选择所有给出祖先选择器的子孙选择器. 例子: <!doctype html> <html lang='zh'> <h ...

  9. How many ways??(HDU 2157)

    How many ways?? Sample Input 4 4 //n个点,m条路径0 1 //s->t可通0 21 32 32 //询问数0 3 2 //从0到3走两条路可到的方案有多少种0 ...

  10. App 冷启动:给 Android 的 Activity 添加一个背景

    2016/8/8 11:11:18 # 纠错 之前写的这篇内容的知识点有误,给大家造成了误导,深感抱歉. android 中给 Activity 设置背景的方法是在 style 文件中设置 windo ...