福昕阅读器drm加密解密总结

drm是数字版权保护的一种方式,前一段时间在做四川文轩数字图书馆项目的时候用到了相关的知识,感觉这东西对于一些在线阅读和视频播放还是有很大用处的。

对于其工作原理我也很好奇,先摘抄度娘的内容如下,当然你也可以直接访问度娘:http://baike.baidu.com/view/47310.htm?fr=aladdin

DRM技术的工作原理是,首先建立数字节目授权中心。编码压缩后的数字节目内容,可以利用 密钥(Key)进行加密保护(lock),加密的数字节目头部存放着KeyID和节目授权中心的URL。用户在点播时,根据节目头部的KeyID和URL信息,就可以通过数字节目 授权中心的验证授权后送出相关的 密钥解密(unlock),节目方可播放。
需要保护的节目被加密,即使被用户下载保存,没有得到数字节目授权中心的验证授权也无法播放,从而严密地保护了节目的版权。
 
密钥一般有两把,一把 公钥(public key),一把 私钥(private key)。 公钥用于加密节目内容本身, 私钥用于解密节目,私钥还可以防止当节目头部有被改动或破坏的情况,利用 密钥就可以判断出来,从而阻止节目被非法使用。 上述这种加密的方法,有一个明显的缺陷,就是当解密的 密钥在发送给用户时,一旦被 黑客获得密钥,即可方便解密节目,从而不能真正确保节目内容提供商的实际版权利益。另一种更加安全的加密方法是使用三把 密钥,即把密钥分成两把,一把存放在用户的Pc机上,另一把放在验证站(access ticket)。要解密数字节目,必须同时具备这两把 密钥,方能解开数字节目。
毫无疑问,加密保护技术在开发 电子商务系统中正起着重要的防盗版作用。比如,在互联网上传输音乐或视频节目等内容,这些内容很容易被拷贝复制。为了避免这些风险,节目内容在互联网上传输过程中一般都要经过加密保护。也就是说,收到加密的数字节目的人必须有一把 密钥(key)才能打开数字节目并播放收看。因此,传送 密钥的工作必须紧跟在加密节目传输之后。
对内容提供商而言,必须意识到传送 密钥工作的重要性,要严防密钥在传送时被窃取。互联网上的黑客总是喜欢钻这些漏洞。因此我们需要一种安全的严密的方式传送 密钥,以保证全面实现安全保护机制。
市场上比较多应用的是 微软的 DRM 技术。

系统原理

系统会将 密钥标识和许可证颁发机构地址写入打包加密后的内容的头部,并且使用另一对密钥。
通过椭圆曲线 加密算法对头部信息进行签名,防止头部信息被非法修改。
内容部分的加密过程可以简单描述为,首先使用SHA-1散列算法处理56位 密钥,得到一个160位,即20 字节的密钥散列。
这个 密钥散列的前12字节将用作生成加密过程中使用的密钥。
这12个字节将作为一个 密钥,通过RC4算法加密一个全零的64字节串,得到一个64字节的加密结果。
其前48字节,即12个32位字作为产生加密内容使用的 密钥的来源,分别针对前面6个32位字的和后面6个32位字进行操作。对于被加密的内容来说,首先把被加密的内容切分为8个字节的 数据块。
对于每一个8个字节的 数据块,它的前32位数据将和上述 密钥的前面6个32位字的进行运算,后32位数据将和上述密钥的后面6个字节进行运算。
具体运算过程是,32位数据与6个32位字的的 密钥的第一节字节相乘,然后除以4294967296,取其余数,并交换结果的高16位和低16位,然后再与6个32位字的的密钥的第二节字节相乘,然后除以4294967296取其余数,并交换结果的高16位和低16位,然后再与6个32位字的的密钥的第三节字节相乘,然后除以4294967296取其余数,并交换结果的高16位和低16位,然后再与6个字节的密钥的第四节字节相乘,然后除以4294967296取其余数,并交换结果的高16位和低16位,然后再与6个32位字的的密钥的第一节字节相乘,然后除以4294967296取其余数,并交换结果的高16位和低16位,然后再加上6个32位字的密钥,然后除以4294967296取其余数,上述过程定义为函数f(x),设一个64位状态值,并设初值为零。
 
说了太多的废话,这玩意儿到底怎么用还没说,下面来点干货,上代码
  1 /**
  2  * 文件名 BaseFoac.java
  3  * 包含类名列表 com.issmobile.numlibrary.tool
  4  * 版本信息  版本号 
  5  * 创建日期 2014年7月15日
  6  * 版权声明 
  7  */
  8 
  9 package com.issmobile.numlibrary.tool;
 10 
 11 import java.io.BufferedReader;
 12 import java.io.InputStreamReader;
 13 import java.net.InetAddress;
 14 
 15 import org.apache.http.HttpEntity;
 16 import org.apache.http.HttpResponse;
 17 import org.apache.http.client.CookieStore;
 18 import org.apache.http.client.methods.HttpPost;
 19 import org.apache.http.entity.StringEntity;
 20 import org.apache.http.impl.client.AbstractHttpClient;
 21 import org.apache.http.impl.client.DefaultHttpClient;
 22 import org.apache.http.params.CoreConnectionPNames;
 23 
 24 import android.util.Log;
 25 
 26 import com.foxit.general.BufferFileRead;
 27 import com.foxit.general.DrmNative;
 28 import com.foxit.general.PdfBaseDef;
 29 import com.foxit.general.PdfDocNative;
 30 import com.foxit.general.PdfDrmNative;
 31 import com.foxit.general.ObjectRef;
 32 import com.foxit.general.PdfSecurityNative;
 33 import com.foxit.general.RsaKey;
 34 import com.foxit.general.RtBaseDef;
 35 import com.foxit.general.RtNative;
 36 
 37 /**
 38 *  类名 
 39 *  @author 王洪贺
40 * 实现的主要功能。 41 * 创建日期 2014年7月15日 42 */ 43 44 public class BaseFoac { 45 46 protected ObjectRef m_encryptParams = null; 47 private CookieStore m_cookieStore = null; 48 private byte[] m_decoderPubKey = null; 49 50 /**用户名*/ 51 private String mUserName; 52 /**密码*/ 53 private String mPassword; 54 /**密码*/ 55 private String mDevSN; 56 57 private String m_host = null; 58 private String m_port = null; 59 private String m_object = null; 60 private ObjectRef security = null; 61 private RsaKey m_rsaKey = null; 62 /**文件本地地址*/ 63 private String drmfile = null; 64 private DefaultHttpClient httpClient = null;//new DefaultHttpClient(); 65 private String m_sessionID = null; 66 67 /** 68 * 获取信封的时候初始化,需要用户名密码 69 * */ 70 public BaseFoac(String mUserName, String mPassword, String drmfile) { 71 this.mUserName = "ElibUser." + mUserName; 72 this.mPassword = mPassword; 73 this.mDevSN = mPassword; 74 this.drmfile = drmfile; 75 } 76 77 /** 78 * 解密文件的时候初始化 79 * */ 80 public BaseFoac() { 81 } 82 83 public void setDRMFileName(String filename) { 84 drmfile = filename; 85 } 86 87 public boolean isDocWrapper(ObjectRef document) { 88 if (!PdfDrmNative.isDocWrapper(document)) 89 return false; 90 return true; 91 } 92 93 public boolean isFoxitDRM(ObjectRef document) { 94 if (!PdfDrmNative.isDocWrapper(document)) 95 return false; 96 97 m_encryptParams = PdfDrmNative.getEncryptParams(document); 98 99 if (m_encryptParams == null) 100 return false; 101 102 return true; 103 } 104 105 protected String getServiceURL() { 106 //TODO 获取到书籍中验证drm的网址,由于目前服务器不可用,返回默认地址,正式版修改回来 107 // return PdfDrmNative.getEncryptParamsItemString(m_encryptParams, 108 // PdfBaseDef.ENCRYPTPARAMS_SERVICEURL); 109 return URLConstants.licenseURL; 110 } 111 112 /** 113 * 解析网址 114 */ 115 protected void parseURL(String serviceUrl) { 116 if (serviceUrl == null) 117 return; 118 int hostIndex = serviceUrl.indexOf("://"); 119 String tmp = serviceUrl.substring(hostIndex + 3); 120 int objIndex = tmp.indexOf("/"); 121 int portIndex = tmp.indexOf(":"); 122 if (portIndex < 0) { 123 m_port = "80"; 124 m_host = tmp.substring(0, objIndex); 125 } else { 126 m_port = tmp.substring(portIndex + 1, objIndex); 127 m_host = tmp.substring(0, portIndex); 128 } 129 m_object = tmp.substring(objIndex + 1); 130 } 131 132 /** 133 * 获取开始的请求信息 134 */ 135 protected String getSessionBeginRequest(String sessionID) { 136 ObjectRef foac = DrmNative.createFoac(true); 137 if (foac == null) 138 return null; 139 140 DrmNative.setFoacSessionID(foac, sessionID); 141 142 ObjectRef category = DrmNative.getFoacDataCategory(foac); 143 if (category == null) { 144 DrmNative.deleteFoac(foac); 145 return null; 146 } 147 148 DrmNative.setFoacRequestID(foac, "SessionBegin"); 149 150 ObjectRef subCategory = DrmNative.addSubCategory(category, "FlowCode", true); 151 String flowCode = PdfDrmNative.getEncryptParamsItemString(m_encryptParams, 152 PdfBaseDef.ENCRYPTPARAMS_FLOWCODE); 153 DrmNative.setCategoryAttribute(subCategory, "Value", flowCode); 154 155 String request = DrmNative.saveFoac(foac); 156 DrmNative.deleteFoac(foac); 157 return "XmlContent=" + request; 158 } 159 160 /** 161 * 发送请求信息并返回接受到的数据,需访问网络 162 */ 163 protected String sendAndReceive(String bsSend) { 164 String result = null; 165 try { 166 httpClient = new DefaultHttpClient(); 167 String temp = bsSend.replace("&", "%26"); 168 temp = temp.replace("+", "%2B"); 169 InetAddress addr = InetAddress.getByName(m_host); 170 171 String url; 172 if (addr.toString().substring(1).indexOf("/") != -1) 173 url = "http://" + m_host + ":" + m_port + "/" + m_object; 174 else 175 url = "http://" + m_host + ":" + m_port + "/" + m_object; 176 HttpPost httpPost = new HttpPost(url); 177 HttpEntity entity = new StringEntity(temp); 178 httpPost.setEntity(entity); 179 180 httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8"); 181 182 // if (m_cookieStore != null) 183 httpClient.setCookieStore(m_cookieStore); 184 185 httpClient.getParams().setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 300000); 186 httpClient.getParams().setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 300000); 187 188 HttpResponse httpResponse = httpClient.execute(httpPost); 189 int status = httpResponse.getStatusLine().getStatusCode(); 190 long len = httpResponse.getEntity().getContentLength(); 191 192 StringBuilder builder = new StringBuilder(); 193 BufferedReader reader = new BufferedReader(new InputStreamReader(httpResponse 194 .getEntity().getContent())); 195 for (String s = reader.readLine(); s != null; s = reader.readLine()) { 196 builder.append(s); 197 } 198 result = builder.toString(); 199 m_cookieStore = ((AbstractHttpClient) httpClient).getCookieStore(); 200 201 if (result.indexOf("xml") == -1) 202 return null; 203 204 } catch (Exception e) { 205 e.printStackTrace(); 206 } 207 return result; 208 } 209 210 /** 211 * 解析收到的信息 212 */ 213 protected void parseSessionBeginRecieve(String receive) { 214 ObjectRef foac = DrmNative.loadFoac(receive.getBytes()); 215 if (foac == null) 216 return; 217 218 String state = DrmNative.getFoacAnswerState(foac); 219 if (state.indexOf("1") > -1) { 220 ObjectRef category = DrmNative.getFoacDataCategory(foac); 221 222 //Pubkey 223 int iCount = DrmNative.countSubCategories(category, "ServerPubKey"); 224 if (iCount == 0) { 225 DrmNative.deleteFoac(foac); 226 return; 227 } 228 ObjectRef subCategory = DrmNative.getSubCategory(category, "ServerPubKey", 0); 229 String bsPubKey = DrmNative.getCategoryAttributeValue(subCategory, "Value"); 230 231 ObjectRef sessionID = DrmNative.getSubCategory(category, "SessionID", 0); 232 m_sessionID = DrmNative.getCategoryAttributeValue(sessionID, "Value"); 233 234 // m_decoderPubKey = Base64.decode(bsPubKey, Base64.DEFAULT); 235 m_decoderPubKey = RtNative.base64Decode(bsPubKey.getBytes(), 0, bsPubKey.length()); 236 } 237 DrmNative.deleteFoac(foac); 238 } 239 240 /** 241 * 加密字符串 242 */ 243 protected String EncryptString(String str) { 244 byte[] data = DrmNative.pkiRsaEncrypt(str, m_decoderPubKey); 245 //return Base64.encodeToString(data, Base64.DEFAULT); 246 return RtNative.base64EncodeToString(data, 0, data.length); 247 } 248 249 /** 250 * 获取检查账户的请求信息 251 */ 252 protected String GetCheckAccountRequest(String sessionID) { 253 String fileID = PdfDrmNative.getEncryptParamsItemString(m_encryptParams, 254 PdfBaseDef.ENCRYPTPARAMS_FILEID); 255 String strFileID = EncryptString(fileID); 256 257 String order = PdfDrmNative.getEncryptParamsItemString(m_encryptParams, 258 PdfBaseDef.ENCRYPTPARAMS_ORDER); 259 String strOrder = EncryptString(order); 260 261 String account = EncryptString(mUserName); 262 String password = EncryptString(mPassword); 263 264 ObjectRef foac = DrmNative.createFoac(true); 265 DrmNative.setFoacSessionID(foac, sessionID); 266 267 DrmNative.setFoacRequestID(foac, "AuthAccount"); 268 269 ObjectRef category = DrmNative.getFoacDataCategory(foac); 270 if (category == null) { 271 DrmNative.deleteFoac(foac); 272 return null; 273 } 274 275 ObjectRef subCategory = DrmNative.addSubCategory(category, "EncryptAccount", true); 276 DrmNative.setCategoryAttribute(subCategory, "Value", account); 277 278 subCategory = DrmNative.addSubCategory(category, "EncryptPassword", true); 279 DrmNative.setCategoryAttribute(subCategory, "Value", password); 280 281 subCategory = DrmNative.addSubCategory(category, "EncryptOrderID", true); 282 DrmNative.setCategoryAttribute(subCategory, "Value", strOrder); 283 284 subCategory = DrmNative.addSubCategory(category, "EncryptFileID", true); 285 DrmNative.setCategoryAttribute(subCategory, "Value", strFileID); 286 287 String request = DrmNative.saveFoac(foac); 288 289 DrmNative.deleteFoac(foac); 290 291 return "XmlContent=" + request; 292 } 293 294 /** 295 * 解析收到账户认证的信息 296 */ 297 protected boolean ParseCheckAccountRequest(String receive) { 298 ObjectRef foac = DrmNative.loadFoac(receive.getBytes()); 299 if (foac == null) 300 return false; 301 302 boolean bRet = false; 303 304 ///foac verify 305 String bsState = DrmNative.getFoacAnswerState(foac); 306 if (bsState.equals("1")) { 307 ObjectRef category = DrmNative.getFoacDataCategory(foac); 308 309 int iCount = DrmNative.countSubCategories(category, "Result"); 310 if (iCount == 0) { 311 DrmNative.deleteFoac(foac); 312 return false; 313 } 314 ObjectRef subCategory = DrmNative.getSubCategory(category, "Result", 0); 315 String result = DrmNative.getCategoryAttributeValue(subCategory, "Value"); 316 bRet = result.equals("1"); 317 } 318 DrmNative.deleteFoac(foac); 319 return bRet; 320 } 321 322 /** 323 * 获取信封请求信息 324 */ 325 public String GetEnvelopRequest(String sessionID) { 326 String fileID = PdfDrmNative.getEncryptParamsItemString(m_encryptParams, 327 PdfBaseDef.ENCRYPTPARAMS_FILEID); 328 String strFileID = EncryptString(fileID); 329 330 String order = PdfDrmNative.getEncryptParamsItemString(m_encryptParams, 331 PdfBaseDef.ENCRYPTPARAMS_ORDER); 332 String strOrder = order;//EncryptString(order); 333 334 String userName = mUserName;//EncryptString(m_userName); 335 String password = EncryptString(mPassword); 336 String devSn = EncryptString(mDevSN); 337 338 byte[] seed = { 339 'F', 'o', 'x', 'i', 't', 'A', 'n', 'd', 'r', 'o', 'i', 'd' 340 }; 341 342 m_rsaKey = DrmNative.createRsaKey(1024, seed, null); 343 344 if (m_rsaKey == null) 345 return null; 346 347 String strClientPubKey = RtNative.base64EncodeToString(m_rsaKey.publicKey, 0, 348 m_rsaKey.publicKey.length); 349 // String strClientPubKey = Base64.encodeToString(clientPubKey, Base64.DEFAULT); 350 351 ObjectRef foac = DrmNative.createFoac(true); 352 DrmNative.setFoacSessionID(foac, sessionID); 353 354 DrmNative.setFoacRequestID(foac, "GetEnvelop"); 355 356 ObjectRef category = DrmNative.getFoacDataCategory(foac); 357 if (category == null) { 358 DrmNative.deleteFoac(foac); 359 return null; 360 } 361 362 ObjectRef subCategory = DrmNative.addSubCategory(category, "OrderID", true); 363 DrmNative.setCategoryAttribute(subCategory, "Value", strOrder); 364 365 subCategory = DrmNative.addSubCategory(category, "EncryptFileID", true); 366 DrmNative.setCategoryAttribute(subCategory, "Value", strFileID); 367 368 subCategory = DrmNative.addSubCategory(category, "ClientPubKey", true); 369 DrmNative.setCategoryAttribute(subCategory, "Value", strClientPubKey); 370 371 subCategory = DrmNative.addSubCategory(category, "Usermail", true); 372 DrmNative.setCategoryAttribute(subCategory, "Value", userName); 373 374 subCategory = DrmNative.addSubCategory(category, "EncryptPassword", true); 375 DrmNative.setCategoryAttribute(subCategory, "Value", password); 376 377 subCategory = DrmNative.addSubCategory(category, "EncryptDeviceSN", true); 378 DrmNative.setCategoryAttribute(subCategory, "Value", devSn); 379 380 String request = DrmNative.saveFoac(foac); 381 382 DrmNative.deleteFoac(foac); 383 384 return "XmlContent=" + request; 385 } 386 387 /** 388 * 解析收到的信封信息 389 */ 390 public boolean parseEnvelopRequest(ObjectRef document, String receive) { 391 392 BufferFileRead bufReader = new BufferFileRead(receive.getBytes(), 0); 393 ObjectRef envelope = DrmNative.loadEnvelope(bufReader); 394 byte[] key = DrmNative.getEnvelopeKey(envelope); 395 396 String algorithm = DrmNative.getEnvelopeAlgorithm(envelope); 397 byte[] deKey = DrmNative.pkiRsaDecrypt(key, m_rsaKey.privateKey); 398 399 security = new ObjectRef(); 400 String filter = "FoxitSTD"; 401 int ret = PdfSecurityNative.createFoxitDRMSecurity(filter, 402 algorithm.equals("FOXIT_ENCRYPT2") ? RtBaseDef.CIPHER_AES : RtBaseDef.CIPHER_RC4, 403 deKey, security); 404 if (ret != RtBaseDef.ERR_SUCCESS) 405 return false; 406 407 int offset = PdfDrmNative.getDocWrapperOffset(document); 408 boolean flag = PdfSecurityNative.verifyFoxitDRMSecurity(security); 409 410 ret = PdfDocNative.closeDoc(document); 411 if (ret != RtBaseDef.ERR_SUCCESS) 412 return false; 413 414 ret = PdfDocNative.loadDoc(drmfile, 0, offset, document); 415 if (ret != RtBaseDef.ERR_SUCCESS) 416 return false; 417 418 return true; 419 } 420 421 /** 422 * 解密文件 423 */ 424 public boolean decrypt(ObjectRef document) { 425 if (document == null) 426 return false; 427 428 String serviceUrl = getServiceURL(); 429 if (serviceUrl == null) 430 return false; 431 parseURL(serviceUrl); 432 System.out.println("URL ==" + serviceUrl); 433 434 String sessionID = "6F9629FF-8A86-D011-B42D-00C04FC964FF"; 435 String send = getSessionBeginRequest(sessionID); 436 if (send == null) 437 return false; 438 String receive = sendAndReceive(send); 439 if (receive == null) 440 return false; 441 parseSessionBeginRecieve(receive); 442 443 String checkAccount = GetCheckAccountRequest(sessionID); 444 if (checkAccount == null) 445 return false; 446 receive = sendAndReceive(checkAccount); 447 if (receive == null) 448 return false; 449 if (!ParseCheckAccountRequest(receive)) 450 return false; 451 452 String envelope = GetEnvelopRequest(sessionID); 453 if (envelope == null) 454 return false; 455 receive = sendAndReceive(envelope); 456 if (receive == null) 457 return false; 458 459 return parseEnvelopRequest(document, receive); 460 } 461 462 /** 463 * 获取信封 464 * @author honghe 465 */ 466 public String getEnvelop(ObjectRef document) { 467 if (document == null) 468 return null; 469 470 String serviceUrl = getServiceURL(); 471 if (serviceUrl == null) 472 return null; 473 parseURL(serviceUrl); 474 System.out.println("URL ==" + serviceUrl); 475 476 String sessionID = "6F9629FF-8A86-D011-B42D-00C04FC964FF"; 477 String send = getSessionBeginRequest(sessionID); 478 if (send == null) 479 return null; 480 String receive = sendAndReceive(send); 481 if (receive == null) 482 return null; 483 parseSessionBeginRecieve(receive); 484 485 String checkAccount = GetCheckAccountRequest(sessionID); 486 if (checkAccount == null) 487 return null; 488 receive = sendAndReceive(checkAccount); 489 if (receive == null) 490 return null; 491 if (!ParseCheckAccountRequest(receive)) 492 return null; 493 494 String envelope = GetEnvelopRequest(sessionID); 495 if (envelope == null) 496 return null; 497 receive = sendAndReceive(envelope); 498 if (receive == null) 499 return null; 500 501 return receive; 502 } 503 504 /** 505 * 根据信封信息解密文档 506 * @author honghe 507 */ 508 public boolean decryptDoc(ObjectRef document, String receive) { 509 BufferFileRead bufReader = new BufferFileRead(receive.getBytes(), 0); 510 ObjectRef envelope = DrmNative.loadEnvelope(bufReader); 511 byte[] key = DrmNative.getEnvelopeKey(envelope); 512 String algorithm = DrmNative.getEnvelopeAlgorithm(envelope); 513 byte[] seed = { 514 'F', 'o', 'x', 'i', 't', 'A', 'n', 'd', 'r', 'o', 'i', 'd' 515 }; 516 m_rsaKey = DrmNative.createRsaKey(1024, seed, null); 517 byte[] deKey = DrmNative.pkiRsaDecrypt(key, m_rsaKey.privateKey); 518 519 security = new ObjectRef(); 520 String filter = "FoxitSTD"; 521 int ret = PdfSecurityNative.createFoxitDRMSecurity(filter, 522 algorithm.equals("FOXIT_ENCRYPT2") ? RtBaseDef.CIPHER_AES : RtBaseDef.CIPHER_RC4, 523 deKey, security); 524 if (ret != RtBaseDef.ERR_SUCCESS) 525 return false; 526 527 int offset = PdfDrmNative.getDocWrapperOffset(document); 528 boolean flag = PdfSecurityNative.verifyFoxitDRMSecurity(security); 529 530 ret = PdfDocNative.closeDoc(document); 531 if (ret != RtBaseDef.ERR_SUCCESS) 532 return false; 533 534 ret = PdfDocNative.loadDoc(drmfile, 0, offset, document); 535 if (ret != RtBaseDef.ERR_SUCCESS) 536 return false; 537 538 return true; 539 } 540 541 public void destroy() { 542 int ret = RtBaseDef.ERR_ERROR; 543 if (m_encryptParams != null) 544 ret = PdfDrmNative.releaseEncryptParams(m_encryptParams); 545 if (security != null) 546 ret = PdfSecurityNative.destroySecurity(security); 547 548 } 549 550 }

简单的说一下调用的过程:

1.首先用客户端下载一本经过drm加密的书籍(加密的过程是文轩那边已经加密好的了)

2.下载完后根据书籍中的drm地址和加密信息以及用户的用户名和密码获取信封(按照福昕提供的api是在阅读的时候在线联网解密的,但客户要求可以离线阅读,因此下载书的时候要先取得解密用的信封)

获取信封的调用方法

 1 if(finished) {
 2                     FoxitRAMManager.getInstance();
 3                     ObjectRef document = new ObjectRef();
 4                     int result = PdfDocNative.loadDoc(book.loc, null, document);
 5                     if (result != RtBaseDef.ERR_SUCCESS) {
 6                          throw new Exception("load drm fail!");
 7                     }
 8                     User user = AppContext.getInstance().getUserModel().user;
 9                     BaseFoac baseFoac = new BaseFoac(user.uName, user.pwd, book.loc);
10                     if (baseFoac.isFoxitDRM(document)) {
11                         baseFoac.setDRMFileName(book.loc);
12                         String envelop = baseFoac.getEnvelop(document);
13                         if (envelop != null) {
14                             book.receive = envelop;
15                         }
16                         else {
17                             throw new Exception("get envelop fail!");
18                         }
19                     }
20                    // baseFoac.destroy();
21                     PdfDocNative.closeDoc(document);
22             }

 

3.将获取的信封根据书籍对应的信息保存到数据库中,一本书一个用来解密的信封。

4.用户打开书籍的时候获取该书籍存储于数据库中的信封,用信封对书籍进行解密,用户就可以看到该书籍了。

 1  FoxitRAMManager.getInstance();
 2         document = new ObjectRef();
 3         int result = PdfDocNative.loadDoc(filePath, null, document);
 4         if (result != RtBaseDef.ERR_SUCCESS)
 5             return false;
 6         // 根据得到的信封解密书籍
 7         mBaseFoac = new BaseFoac();
 8         if (mBaseFoac.isDocWrapper(document)) {
 9             mBaseFoac.setDRMFileName(filePath);
10             if (!mBaseFoac.decryptDoc(document, receive)) {
11                 return false;
12             }
13         } else {
14             return false;
15         }

 

这样做的好处是该用户下载的书籍用其他的阅读器是无法打开的,而且解密的信封也是跟用户和服务器相关的,其他人或者是不联网验证也是无法查看传送的书籍的,有效的保护了数字版权。

 

 

代码已上传github。

地址为:https://github.com/dongweiq/study/tree/master/pdf_drm

代码中appid和password已删除,此外你只有加入jar包和so文件才可以运行。

我的github地址:https://github.com/dongweiq/study

欢迎关注,欢迎star o(∩_∩)o 。有什么问题请邮箱联系 [email protected] qq714094450

你可能感兴趣的:(java,数据库,移动开发)