• 福昕阅读器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 王洪贺<br/>
     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 。有什么问题请邮箱联系 dongweiqmail@gmail.com qq714094450

  • 相关阅读:
    (简单) POJ 3414 Pots,BFS+记录路径。
    (简单) POJ 3087 Shuffle'm Up,枚举。
    (简单) POJ 3126 Prime Path,BFS。
    (简单) POJ 1426 Find The Multiple,BFS+同余。
    (简单) POJ 3279 Fliptile,集合枚举。
    (简单) POJ 1278 Catch That Cow,回溯。
    (简单) POJ 2251 Dungeon Master,BFS。
    (简单) POJ 1321 棋盘问题,回溯。
    回溯---输出二叉树中所有从根到叶子的路径
    回溯---在矩阵中寻找字符串
  • 原文地址:https://www.cnblogs.com/dongweiq/p/3981659.html
Copyright © 2020-2023  润新知