以前用 C++ 做过的 DRM 项目,现抽取出其中核心的代码, 演示一下如何借助 DRM 对流媒体文件进行保护。
虽然微软的 DRM 技术被破解了, 但那是以用户通过认证并下载证书为前提的。由是观之, 运用 DRM 对流媒体
文件施以保护仍有一定意义,这毕竟比什么都不做要强嘛!
/* drm.h*/
#ifndef __DRM_H__
#define __DRM_H__
#include <string>
#import "wmrmobjs.dll"
class DRMObject {
public:
DRMObject(char* inFile, char* outFile, char* licenseURL, char* corpName);
bool Encrypt();
public:
std::string key;
std::string seed;
std::string keyID;
std::string contentID;
std::string publicKey;
std::string privateKey;
private:
std::string _inFile;
std::string _outFile;
std::string _corpName;
std::string _licenseURL;
};
#endif
// drm.cxx
#include "drm.h"
#include <comdef.h>
#include <iostream>
DRMObject::DRMObject(char* inFile, char* outFile, char* licenseURL, char* corpName)
{
_inFile = inFile;
_outFile = outFile;
_corpName = corpName;
_licenseURL = licenseURL;
}
bool DRMObject::Encrypt()
{
try {
HRESULT hr;
// Initialize the COM library on the current thread
hr = CoInitialize(NULL);
if (FAILED(hr))
_com_issue_error(hr);
WMRMOBJSLib::IWMRMKeysPtr keysObj("Wmrmobjs.WMRMKeys");
WMRMOBJSLib::IWMRMHeaderPtr headerObj("Wmrmobjs.WMRMHeader");
WMRMOBJSLib::IWMRMProtectPtr protectObj("Wmrmobjs.WMRMProtect");
// Generate keyID,seed,contentID
keyID = keysObj->GenerateKeyID();
seed = keysObj->GenerateSeed();
contentID = keysObj->GenerateKeyID();
// Generate key
keysObj->KeyID = keyID.c_str();
keysObj->Seed = seed.c_str();
key = keysObj->GenerateKey();
// Set protected header
headerObj->KeyID = keyID.c_str();
headerObj->ContentID = contentID.c_str();
headerObj->LicenseAcqURL = _licenseURL.c_str();
headerObj->Attribute["Copyright"] = _corpName.c_str();
// verify the key
headerObj->SetCheckSum(key.c_str());
//Generate public and private key
_variant_t privKey, pubKey;
VariantInit(&privKey);
VariantInit(&pubKey);
keysObj->GenerateSigningKeys(&privKey, &pubKey);
headerObj->IndividualizedVersion = "2.2";
// Save private and public kyes
privateKey = (_bstr_t)privKey;
publicKey = (_bstr_t)pubKey;
// Sign key
headerObj->Sign((_bstr_t)privKey);
// Set protect object
_bstr_t header;
header = headerObj->Header;
protectObj->Header = header;
protectObj->Key = key.c_str();
protectObj->V1KeyID = keyID.c_str();
// start encrypt
protectObj->InputFile = _inFile.c_str();
protectObj->ProtectFile(_outFile.c_str());
}
catch (const _com_error& e) {
std::cerr << "COM Exception: "
<< e.ErrorMessage()
<< std::endl;
if (e.ErrorInfo())
std::cerr << (char*)e.ErrorInfo()
<< std::endl;
return false;
}
CoUninitialize();
return true;
}
// drm_test.cxx
#include "drm.h"
#include <iostream>
using namespace std;
int main() {
DRMObject* drmObj = new DRMObject("d:\\test.wma",
"d:\\test2.wma",
"http://localhost/test.asp",
"test corp");
if (drmObj->Encrypt()) {
cout << "KeyID: "
<< drmObj->keyID
<< endl;
cout << "Seed: "
<< drmObj->seed
<< endl;
cout << "Key: "
<< drmObj->key
<< endl;
cout << "ContentID: "
<< drmObj->contentID
<< endl;
cout << "Public Key: "
<< drmObj->publicKey
<< endl;
cout << "Private Key: "
<< drmObj->privateKey
<< endl;
}
delete drmObj;
}