package com.web;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.CipherOutputStream;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.lang.StringUtils;
/**
*
* 加密解密测试
* <功能详细描述>
*
* @author Vincent
* @version [版本号, 2014-10-10]
* @see [相关类/方法]
* @since [产品/模块版本]
*/
public class TestEncode
{
private Cipher cipher;
private byte[] iv = new byte[16];
private long plainTextLen;
private static int GENE1 = 0x7F;
private static int GENE2 = 0x80;
private static String DEFAULT_CONTENT_TYPE = "application/java";
private static String ENCRYPT_METHOD_WHOLE = "whole";
private static String ENCRYPT_METHOD_BLOCK = "block";
private static String ALGORITHM_AES = "AES";
private static String AES_CBC_PKCS5PADDING = "AES/CBC/PKCS5Padding";
private String contentType = DEFAULT_CONTENT_TYPE;
public String getContentType()
{
return contentType;
}
public void setContentType(String contentType)
{
this.contentType = contentType;
}
public TestEncode()
throws Exception
{
cipher = getCipher(AES_CBC_PKCS5PADDING);
}
private Cipher getCipher(String transformation)
throws Exception
{
return Cipher.getInstance(transformation);
}
public void setIv()
{
iv = new byte[16];
SecureRandom sec = new SecureRandom();
sec.nextBytes(iv);
}
public byte[] getIv(RandomAccessFile file)
throws Exception
{
byte[] iv = new byte[16];
for (int i = 0; i < iv.length; i++)
{
iv[i] = file.readByte();
}
return iv;
}
/**
* long的univar表示
*
* @param len long型数
* @return univar表示
*/
public byte[] parseLong2Unitvar(long len)
{
if (len <= 0)
{
return null;
}
byte a;
long k;
ByteArrayOutputStream os = new ByteArrayOutputStream();
k = len;
a = (byte)(k & GENE1);
os.write(a);
k = k >> 7;
while (k != 0)
{
a = (byte)(k & GENE1);
a = (byte)(k | GENE2);
os.write(a);
k = k >> 7;
}
byte[] ba = os.toByteArray();
byte tmp = -1;
int length = ba.length - 1;
try
{
os.reset();
os.close();
}
catch (IOException e)
{
}
for (int i = 0; i <= length / 2; i++)
{
tmp = ba[i];
ba[i] = ba[length - i];
ba[length - i] = tmp;
}
return ba;
}
/**
* univar的long表示
*
* @param len long型数
* @return univar表示
*/
public long parseUnitvar2Long(byte[] bytes)
{
long l = 0l;
byte tmp = -1;
int length = bytes.length - 1;
for (int i = 0; i <= length / 2; i++)
{
tmp = bytes[i];
bytes[i] = bytes[length - i];
bytes[length - i] = tmp;
}
for (int i = 0; i <= length; i++)
{
l |= ((((bytes[i] & 0xffL) & 0x7f)) << (i * 7));
}
return l;
}
/**
* univar的long表示
*
* @param file
* @return
*/
@SuppressWarnings("unused")
public long[] parseUnitvar2Long(RandomAccessFile file)
throws Exception
{
long[] arr = new long[2];
long l = 0l;
byte b = 0;
b = file.readByte();
int i = 0;
long byteNum = 0;
while ((i = b & 0x80) != 0)
{
byteNum++;
l |= (b & 0x7F);
l <<= 7;
b = file.readByte();
}
l |= b;
byteNum += 1;
arr[0] = byteNum;
arr[1] = l;
return arr;
}
public void initalEnCrypt(byte[] key)
throws Exception
{
SecretKeySpec keyspec = new SecretKeySpec(key, ALGORITHM_AES);
IvParameterSpec ivspec = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
}
public CipherOutputStream initalEnCryptStream(OutputStream fos, byte[] key)
throws Exception
{
initalEnCrypt(key);
return new CipherOutputStream(fos, cipher);
}
public OutputStream getCipherOutputStream(OutputStream os, String contentId)
throws Exception
{
OutputStream cos = initalEnCryptStream(os, getKey(contentId));
return cos;
}
private long getAESCBCPaddingLength(long toBeEncryptLength)
{
long encryptLength = toBeEncryptLength + 16 - toBeEncryptLength % 16;
return encryptLength;
}
public long getSecretTextLengthForWhole(long plainTextLen)
{
long encryptLength = getAESCBCPaddingLength(plainTextLen);
// 第一项为加密的密文长度,第二项16为IV的字节数
long result = encryptLength + 16;
return result;
}
public long getSecretTextLengthForBlock(Long plainTextLen, Integer encryptBlockLength, Integer skipBlockLength)
{
long result = 0;
if (skipBlockLength != null && skipBlockLength > 0)
{
// 加密总次数
long times = plainTextLen / (encryptBlockLength + skipBlockLength);
// 需要加密的余数
long remainder = plainTextLen % (encryptBlockLength + skipBlockLength);
if (remainder > encryptBlockLength)
{
remainder = encryptBlockLength;
}
// 待加密的字节长度
long toBeEncryptLength = encryptBlockLength * (times) + remainder;
// 需要AES CBC PKCS5Padding加密的字节,加密后的长度
long encryptedLength = getAESCBCPaddingLength(toBeEncryptLength);
// 第一项为加密的密文长度,第二项为明文的长度,第三项16为IV的字节数
result = encryptedLength + (plainTextLen - toBeEncryptLength) + 16;
}
else
{
// 待加密的字节长度
long toBeEncryptLength = 0;
if (plainTextLen > encryptBlockLength)
{
toBeEncryptLength = encryptBlockLength;
}
else
{
toBeEncryptLength = plainTextLen;
}
// 需要AES CBC PKCS5Padding加密的字节,加密后的长度
long encryptedLength = getAESCBCPaddingLength(toBeEncryptLength);
// 第一项为加密的密文长度,第二项16为IV的字节数
result = encryptedLength + 16;
}
return result;
}
public void writeHeader(OutputStream os, String type, String contentId, Integer encryptBlockLength,
Integer encryptSkipLength)
throws Exception
{
String strContentType = contentType;
String strContentId = contentId;
os.write((byte)0x01);
os.write((byte)strContentType.getBytes().length);
os.write((byte)strContentId.getBytes().length);
os.write(strContentType.getBytes());
os.write(strContentId.getBytes());
long secretTextLength = 0;
if (ENCRYPT_METHOD_WHOLE.equals(type))
{
secretTextLength = getSecretTextLengthForWhole(plainTextLen);
}
else
{
secretTextLength = getSecretTextLengthForBlock(plainTextLen, encryptBlockLength, encryptSkipLength);
}
DCFHeader header = new DCFHeader();
header.setPlainTextLen(plainTextLen);
byte[] headerByte = header.toString().getBytes();
os.write(parseLong2Unitvar(headerByte.length));
os.write(parseLong2Unitvar(secretTextLength));
os.write(headerByte);
os.write(iv);
}
// 分段加密
public void encrypt4Block(String from, String to, String contentId, Integer encryptBlockLength,
Integer encryptSkipLength)
throws Exception
{
InputStream in = null;
OutputStream plainOutputStream = null;
OutputStream ciperOutputStream = null;
try
{
File file = new File(from);
in = new FileInputStream(file);
plainTextLen = file.length();
int maxStreamSize = (int)plainTextLen;
byte[] encryptBlock = new byte[encryptBlockLength];
byte[] skipBlock = null;
if (encryptSkipLength != null && encryptSkipLength > 0)
{
skipBlock = new byte[encryptSkipLength];
}
else
{
skipBlock = new byte[1024];
}
setIv();
plainOutputStream = new FileOutputStream(to);
ciperOutputStream = getCipherOutputStream(plainOutputStream, contentId);
writeHeader(plainOutputStream, ENCRYPT_METHOD_BLOCK, contentId, encryptBlockLength, encryptSkipLength);
boolean startWritePlainText = false;
int n = 0;
int total = 0;
while (true)
{
n = in.read(startWritePlainText ? skipBlock : encryptBlock);
if (n < 0)
{
break;
}
if (n > 0)
{
// 写入密文
if (!startWritePlainText)
{
// 照CBC模式,需要补全明文到16的倍数
int mode = n % 16;
int count = n / 16;
byte[] newEncryptBlock = new byte[(count + 1) * 16];
System.arraycopy(encryptBlock, 0, newEncryptBlock, 0, n);
if (mode == 0)
{
// 补全16个16
for (int i = 0; i < 16; i++)
{
newEncryptBlock[n + i] = (byte)16;
}
}
else
{
// 如mode等于13,就在后面补齐3个3
for (int i = 0; i < 16 - mode; i++)
{
newEncryptBlock[n + i] = (byte)(16 - mode);
}
}
ciperOutputStream.write(newEncryptBlock, 0, newEncryptBlock.length);
ciperOutputStream.flush();
startWritePlainText = true;
}
// 写入明文
else
{
plainOutputStream.write(skipBlock, 0, n);
plainOutputStream.flush();
if (encryptSkipLength != null && encryptSkipLength > 0)
{
startWritePlainText = false;
}
}
total += n;
}
if (total == maxStreamSize) // 读满最大长度则返回
{
break;
}
}
}
catch (Exception e)
{
throw e;
}
finally
{
if (plainOutputStream != null)
{
try
{
plainOutputStream.flush();
plainOutputStream.close();
}
catch (IOException e)
{
}
}
if (ciperOutputStream != null)
{
try
{
ciperOutputStream.flush();
ciperOutputStream.close();
}
catch (IOException e)
{
}
}
}
}
// 全文加密
public void encrypt4Whole(String from, String to, String contentId)
throws Exception
{
InputStream in = null;
OutputStream plainOutputStream = null;
OutputStream ciperOutputStream = null;
try
{
File file = new File(from);
in = new FileInputStream(file);
plainTextLen = file.length();
int maxStreamSize = (int)plainTextLen;
byte[] encriptBlock = new byte[1024];
setIv();
plainOutputStream = new FileOutputStream(to);
ciperOutputStream = getCipherOutputStream(plainOutputStream, contentId);
writeHeader(plainOutputStream, ENCRYPT_METHOD_WHOLE, contentId, null, null);
int n = 0;
int total = 0;
while (true)
{
n = in.read(encriptBlock);
if (n < 0)
{
break;
}
if (n > 0)
{
ciperOutputStream.write(encriptBlock, 0, n);
ciperOutputStream.flush();
total += n;
}
if (total == maxStreamSize) // 读满最大长度则返回
{
break;
}
}
}
catch (Exception e)
{
throw e;
}
finally
{
if (ciperOutputStream != null)
{
try
{
ciperOutputStream.flush();
ciperOutputStream.close();
}
catch (IOException e)
{
}
}
if (plainOutputStream != null)
{
try
{
plainOutputStream.flush();
plainOutputStream.close();
}
catch (IOException e)
{
}
}
}
}
public static byte[] getKey(String contentKey)
throws Exception
{
try
{
return getKey2(contentKey);
}
catch (Exception e)
{
throw e;
}
}
/**
* 根据contentKey生成key
*
* @param contentId 内容ID
* @throws Exception
* @return:key的byte[]
*/
public static byte[] getKey2(String contentKey)
throws Exception
{
String seed = "HUAWEIDRMtadfRkdfoa" + contentKey;
try
{
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sec = SecureRandom.getInstance("SHA1PRNG");
sec.setSeed(seed.getBytes());
kgen.init(128, sec);
Key key = kgen.generateKey();
return key.getEncoded();
}
catch (NoSuchAlgorithmException e)
{
throw e;
}
catch (IllegalStateException e)
{
throw e;
}
}
public static byte[] decryptCBC(byte[] src, byte[] iv, String contentId)
throws Exception
{
try
{
byte[] key = getKey(contentId);
SecretKeySpec keyspec = new SecretKeySpec(key, ALGORITHM_AES);
Cipher cipher = Cipher.getInstance(AES_CBC_PKCS5PADDING);
IvParameterSpec ivspec = new IvParameterSpec(iv);
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
return cipher.doFinal(src);
}
catch (Exception e)
{
throw e;
}
}
// 解密前128个字节
public void decrypt128Byte(String from, String to, String contentId)
throws Exception
{
RandomAccessFile file = null;
ByteArrayOutputStream baos = null;
OutputStream os = null;
try
{
file = new RandomAccessFile(from, "r");
int pos = 1;
byte b = 0;
long[] lArr = null;
// 获取内容类型长度
file.seek(pos);
b = file.readByte();
int contTypeLen = (int)b;
pos += 1;
// 获取内容ID长度
b = file.readByte();
int contIdLen = (int)b;
pos += 1;
// 获取头部长度
pos += contTypeLen + contIdLen;
file.seek(pos);
lArr = parseUnitvar2Long(file);
long headByteLen = lArr[0];
long headContLen = lArr[1];
// 获取加密块长度
lArr = parseUnitvar2Long(file);
long secretByteLen = lArr[0];
long secretContLen = lArr[1];
// 设置加密内容读取位置
pos += headByteLen + secretByteLen + headContLen;
file.seek(pos);
byte[] iv = getIv(file);
byte[] secretBytes = null;
byte[] plainBytes = null;
int i = 0;
int j = 0;
// 获取加密内容
baos = new ByteArrayOutputStream();
secretContLen = secretContLen - 16;
while (j < secretContLen && ((i = file.read()) != -1))
{
baos.write(i);
j++;
}
secretBytes = baos.toByteArray();
plainBytes = decryptCBC(secretBytes, iv, contentId);
os = new FileOutputStream(to);
os.write(plainBytes);
byte[] buff = new byte[1024];
while ((i = file.read(buff)) != -1)
{
os.write(buff, 0, i);
}
}
catch (Exception e)
{
throw e;
}
finally
{
if (baos != null)
{
try
{
baos.close();
}
catch (IOException e)
{
}
}
if (os != null)
{
try
{
os.flush();
os.close();
}
catch (IOException e)
{
}
}
if (file != null)
{
try
{
file.close();
}
catch (IOException e)
{
}
}
}
}
// 解密前128个字节
public void decrypt128Byte4Stream(String from, String to, String contentId)
throws Exception
{
RandomAccessFile file = null;
OutputStream os = null;
CipherOutputStream cos = null;
try
{
file = new RandomAccessFile(from, "r");
int pos = 1;
byte b = 0;
long[] lArr = null;
// 获取内容类型长度
file.seek(pos);
b = file.readByte();
int contTypeLen = (int)b;
pos += 1;
// 获取内容ID长度
b = file.readByte();
int contIdLen = (int)b;
pos += 1;
// 获取头部长度
pos += contTypeLen + contIdLen;
file.seek(pos);
lArr = parseUnitvar2Long(file);
long headByteLen = lArr[0];
long headContLen = lArr[1];
// 获取加密块长度
lArr = parseUnitvar2Long(file);
long secretByteLen = lArr[0];
long secretContLen = lArr[1];
// 设置加密内容读取位置
pos += headByteLen + secretByteLen + headContLen;
file.seek(pos);
byte[] iv = getIv(file);
byte[] key = getKey(contentId);
SecretKeySpec keyspec = new SecretKeySpec(key, ALGORITHM_AES);
Cipher cipher = Cipher.getInstance(AES_CBC_PKCS5PADDING);
IvParameterSpec ivspec = new IvParameterSpec(iv);
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
int i = 0;
int j = 0;
long k = 0;
int len = 1024;
os = new FileOutputStream(to);
cos = new CipherOutputStream(os, cipher);
byte[] bytes = new byte[len];
secretContLen = secretContLen - 16;
// 密文
while (j < secretContLen)
{
k = secretContLen - j;
if (k > len)
{
i = file.read(bytes);
}
else
{
i = file.read(bytes, 0, (int)k);
}
if (-1 != i)
{
cos.write(bytes, 0, i);
}
j = j + i;
}
// 明文
while ((i = file.read(bytes)) != -1)
{
os.write(bytes, 0, i);
}
}
catch (Exception e)
{
throw e;
}
finally
{
if (cos != null)
{
try
{
cos.flush();
cos.close();
}
catch (IOException e)
{
}
}
if (os != null)
{
try
{
os.flush();
os.close();
}
catch (IOException e)
{
}
}
if (file != null)
{
try
{
file.close();
}
catch (IOException e)
{
}
}
}
}
// 全文解密
public void decrypt4Whole(String path, String to, String contentId)
throws Exception
{
RandomAccessFile file = null;
ByteArrayOutputStream baos = null;
OutputStream os = null;
try
{
file = new RandomAccessFile(path, "r");
int pos = 1;
byte b = 0;
long[] lArr = null;
// 获取内容类型长度
file.seek(pos);
b = file.readByte();
int contTypeLen = (int)b;
pos += 1;
// 获取内容ID长度
b = file.readByte();
int contIdLen = (int)b;
pos += 1;
// 获取头部长度
pos += contTypeLen + contIdLen;
file.seek(pos);
lArr = parseUnitvar2Long(file);
long headByteLen = lArr[0];
long headContLen = lArr[1];
// 获取加密块长度
lArr = parseUnitvar2Long(file);
long secretByteLen = lArr[0];
long secretContLen = lArr[1];
// 设置加密内容读取位置
pos += headByteLen + secretByteLen + headContLen;
file.seek(pos);
// 获取加密内容
baos = new ByteArrayOutputStream();
byte[] iv = null;
byte[] secretBytes = null;
byte[] plainBytes = null;
int i = 0;
iv = getIv(file);
while ((i = file.read()) != -1)
{
baos.write(i);
}
secretBytes = baos.toByteArray();
plainBytes = decryptCBC(secretBytes, iv, contentId);
os = new FileOutputStream(to);
os.write(plainBytes);
}
catch (Exception e)
{
throw e;
}
finally
{
if (os != null)
{
try
{
os.flush();
os.close();
}
catch (IOException e)
{
}
}
if (baos != null)
{
try
{
baos.close();
}
catch (IOException e)
{
}
}
if (file != null)
{
try
{
file.close();
}
catch (IOException e)
{
}
}
}
}
// 分段解密
public void decrypt4Block(String from, String to, String contentId, Integer encryptBlockLength,
Integer encryptSkipLength)
throws Exception
{
RandomAccessFile file = null;
OutputStream os = null;
try
{
file = new RandomAccessFile(from, "r");
int pos = 1;
byte b = 0;
long[] lArr = null;
// 获取内容类型长度
file.seek(pos);
b = file.readByte();
int contTypeLen = (int)b;
pos += 1;
// 获取内容ID长度
b = file.readByte();
int contIdLen = (int)b;
pos += 1;
// 获取头部长度
pos += contTypeLen + contIdLen;
file.seek(pos);
lArr = parseUnitvar2Long(file);
long headByteLen = lArr[0];
long headContLen = lArr[1];
// 获取加密块长度
lArr = parseUnitvar2Long(file);
long secretByteLen = lArr[0];
long secretContLen = lArr[1];
// 设置加密内容读取位置
pos += headByteLen + secretByteLen + headContLen;
file.seek(pos);
byte[] iv = getIv(file);
secretContLen = secretContLen - 16;
os = new FileOutputStream(to);
decryptCore4Block(file,
os,
iv,
(int)getAESCBCPaddingLength(encryptBlockLength),
encryptSkipLength,
contentId);
}
catch (Exception e)
{
throw e;
}
finally
{
if (os != null)
{
try
{
os.flush();
os.close();
}
catch (IOException e)
{
}
}
if (file != null)
{
try
{
file.close();
}
catch (IOException e)
{
}
}
}
}
private void decryptCore4Block(RandomAccessFile file, OutputStream os, byte[] iv, int secretContentLen,
int encryptSkipLength, String contentId)
throws Exception
{
byte[] newIv = doDecrypt4Block(file, secretContentLen, os, iv, contentId);
if (newIv == null || newIv.length <= 0)
{
return;
}
int i = 0;
int j = 0;
while (j < encryptSkipLength && (i = file.read()) != -1)
{
os.write(i);
j++;
}
decryptCore4Block(file, os, newIv, secretContentLen, encryptSkipLength, contentId);
}
private byte[] doDecrypt4Block(RandomAccessFile file, long secretContentLen, OutputStream os, byte[] iv,
String contentId)
throws Exception
{
byte[] bytes = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try
{
int i = 0;
int j = 0;
while (j < secretContentLen && ((i = file.read()) != -1))
{
baos.write(i);
j++;
}
byte[] secretBytes = baos.toByteArray();
if (secretBytes != null && secretBytes.length > 0)
{
byte[] plainBytes = decryptCBC(secretBytes, iv, contentId);
bytes = new byte[16];
System.arraycopy(secretBytes, secretBytes.length - 16, bytes, 0, 16);
os.write(plainBytes);
}
}
catch (Exception e)
{
throw e;
}
finally
{
if (baos != null)
{
try
{
baos.flush();
baos.close();
}
catch (IOException e)
{
}
}
}
return bytes;
}
public void getKeyVal(String contentId)
{
try
{
String keyVal = new sun.misc.BASE64Encoder().encode(getKey(contentId));
System.out.println(keyVal);
}
catch (Exception e)
{
e.printStackTrace();
}
}
private class DCFHeader
{
protected final static String ENCRYPTION_METHOD = "Encryption-Method";
protected final static String Encryption_Method = "AES128CBC";
protected final static String PADDING = "padding";
protected final static String Padding_ID = "RFC2630";
protected final static String PLAINTEXTLEN = "plaintextlen";
protected long plainTextLen = 0;
protected final static String RIGHTS_ISSUER = "Rights-Issuer";
protected String rights_Issuer = "";
protected final static String CONTENT_NAME = "Content-Name";
protected String content_Name = "";
protected final static String CONTENT_DSCP = "Content-Description";
protected String content_Dscp = "";
protected final static String CONTENT_VENDOR = "Content_Vendor";
protected String content_Vendor = "";
protected final static String ICON_URI = "Icon-URI";
protected String icon_URI = "";
protected final static String OTHER = "Other-Header";
protected String other_Header = "";
protected final static String ENCRYPTLENGTH = "encryptlen";
protected final static String HWSKIP_BYTES = "HWSkipBytes";
protected String format;
public DCFHeader()
{
}
/**
* @return Returns the content_Dscp.
*/
public String getContent_Dscp()
{
return content_Dscp;
}
/**
* @param content_Dscp The content_Dscp to set.
*/
public void setContent_Dscp(String content_Dscp)
{
this.content_Dscp = content_Dscp;
}
/**
* @return Returns the content_Name.
*/
public String getContent_Name()
{
return content_Name;
}
/**
* @param content_Name The content_Name to set.
*/
public void setContent_Name(String content_Name)
{
this.content_Name = content_Name;
}
/**
* @return Returns the content_Vendor.
*/
public String getContent_Vendor()
{
return content_Vendor;
}
/**
* @param content_Vendor The content_Vendor to set.
*/
public void setContent_Vendor(String content_Vendor)
{
this.content_Vendor = content_Vendor;
}
/**
* @return Returns the icon_URI.
*/
public String getIcon_URI()
{
return icon_URI;
}
/**
* @param icon_URI The icon_URI to set.
*/
public void setIcon_URI(String icon_URI)
{
this.icon_URI = icon_URI;
}
/**
* @return Returns the plainTextLen.
*/
public long getPlainTextLen()
{
return plainTextLen;
}
/**
* @param plainTextLen The plainTextLen to set.
*/
public void setPlainTextLen(long plainTextLen)
{
this.plainTextLen = plainTextLen;
}
/**
* @return Returns the rights_Issuer.
*/
public String getRights_Issuer()
{
return rights_Issuer;
}
/**
* @param rights_Issuer The rights_Issuer to set.
*/
public void setRights_Issuer(String rights_Issuer)
{
this.rights_Issuer = rights_Issuer;
}
public String getFormat()
{
return format;
}
public String toString()
{
StringBuffer sb = new StringBuffer();
// Encryption-Method:AES128CBC
sb.append(ENCRYPTION_METHOD).append(": ").append(Encryption_Method);
// ;padding=RFC2630;plaintextlen=1079
sb.append(";").append(PADDING).append("=").append(Padding_ID);
if (plainTextLen >= 0) // plaintextlen=1079
{
sb.append(";").append(PLAINTEXTLEN).append("=").append(plainTextLen);
}
sb.append("\r\n");
// Rights-Issuer
if (StringUtils.isNotBlank(rights_Issuer))
{
sb.append(RIGHTS_ISSUER).append(": ").append(rights_Issuer).append("\r\n");
}
// Content-Name
if (StringUtils.isNotBlank(content_Name))
{
sb.append(CONTENT_NAME).append(": \"").append(content_Name).append("\"\r\n");
}
// Content-Description
if (StringUtils.isNotBlank(content_Dscp))
{
sb.append(CONTENT_DSCP).append(": \"").append(content_Dscp).append("\"\r\n");
}
// Content_Vendor
if (StringUtils.isNotBlank(content_Vendor))
{
sb.append(CONTENT_VENDOR).append(": \"").append(content_Vendor).append("\"\r\n");
}
// Icon-URI
if (StringUtils.isNotBlank(icon_URI))
{
sb.append(ICON_URI).append(": ").append(icon_URI).append("\r\n");
}
// other: copyright
if (StringUtils.isNotBlank(icon_URI))
{
sb.append(OTHER).append(": \"").append(other_Header).append("\"\r\n");
}
return sb.toString();
}
}
public static void main(String[] args)
throws Exception
{
TestEncode t = new TestEncode();
// t.decrypt128Byte("D:/test/测试DRM加密.txt.dcf", "D:/test/测试DRM加密(解密后).txt", "900000000006");
// t.decrypt128Byte4Stream("D:/test/测试DRM加密.txt.dcf", "D:/test/测试DRM加密(解密后).txt", "900000000006");
// t.decrypt128Byte4Stream("D:/test/img1.jpg.dcf", "D:/test/img1(解密后).jpg", "CNBJTW2600000016224");
//t.encrypt4Block("E:/mypic/cc.jpg", "E:/encodepic/jm.jpg.dcf", "900000000006", 128, 128);
t.decrypt4Block("E:/encodepic/jm.jpg.dcf", "E:/mypic/jiemi.jpg", "900000000006", 128, 128);
}
}
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.CipherOutputStream;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.lang.StringUtils;
/**
*
* 加密解密测试
* <功能详细描述>
*
* @author Vincent
* @version [版本号, 2014-10-10]
* @see [相关类/方法]
* @since [产品/模块版本]
*/
public class TestEncode
{
private Cipher cipher;
private byte[] iv = new byte[16];
private long plainTextLen;
private static int GENE1 = 0x7F;
private static int GENE2 = 0x80;
private static String DEFAULT_CONTENT_TYPE = "application/java";
private static String ENCRYPT_METHOD_WHOLE = "whole";
private static String ENCRYPT_METHOD_BLOCK = "block";
private static String ALGORITHM_AES = "AES";
private static String AES_CBC_PKCS5PADDING = "AES/CBC/PKCS5Padding";
private String contentType = DEFAULT_CONTENT_TYPE;
public String getContentType()
{
return contentType;
}
public void setContentType(String contentType)
{
this.contentType = contentType;
}
public TestEncode()
throws Exception
{
cipher = getCipher(AES_CBC_PKCS5PADDING);
}
private Cipher getCipher(String transformation)
throws Exception
{
return Cipher.getInstance(transformation);
}
public void setIv()
{
iv = new byte[16];
SecureRandom sec = new SecureRandom();
sec.nextBytes(iv);
}
public byte[] getIv(RandomAccessFile file)
throws Exception
{
byte[] iv = new byte[16];
for (int i = 0; i < iv.length; i++)
{
iv[i] = file.readByte();
}
return iv;
}
/**
* long的univar表示
*
* @param len long型数
* @return univar表示
*/
public byte[] parseLong2Unitvar(long len)
{
if (len <= 0)
{
return null;
}
byte a;
long k;
ByteArrayOutputStream os = new ByteArrayOutputStream();
k = len;
a = (byte)(k & GENE1);
os.write(a);
k = k >> 7;
while (k != 0)
{
a = (byte)(k & GENE1);
a = (byte)(k | GENE2);
os.write(a);
k = k >> 7;
}
byte[] ba = os.toByteArray();
byte tmp = -1;
int length = ba.length - 1;
try
{
os.reset();
os.close();
}
catch (IOException e)
{
}
for (int i = 0; i <= length / 2; i++)
{
tmp = ba[i];
ba[i] = ba[length - i];
ba[length - i] = tmp;
}
return ba;
}
/**
* univar的long表示
*
* @param len long型数
* @return univar表示
*/
public long parseUnitvar2Long(byte[] bytes)
{
long l = 0l;
byte tmp = -1;
int length = bytes.length - 1;
for (int i = 0; i <= length / 2; i++)
{
tmp = bytes[i];
bytes[i] = bytes[length - i];
bytes[length - i] = tmp;
}
for (int i = 0; i <= length; i++)
{
l |= ((((bytes[i] & 0xffL) & 0x7f)) << (i * 7));
}
return l;
}
/**
* univar的long表示
*
* @param file
* @return
*/
@SuppressWarnings("unused")
public long[] parseUnitvar2Long(RandomAccessFile file)
throws Exception
{
long[] arr = new long[2];
long l = 0l;
byte b = 0;
b = file.readByte();
int i = 0;
long byteNum = 0;
while ((i = b & 0x80) != 0)
{
byteNum++;
l |= (b & 0x7F);
l <<= 7;
b = file.readByte();
}
l |= b;
byteNum += 1;
arr[0] = byteNum;
arr[1] = l;
return arr;
}
public void initalEnCrypt(byte[] key)
throws Exception
{
SecretKeySpec keyspec = new SecretKeySpec(key, ALGORITHM_AES);
IvParameterSpec ivspec = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
}
public CipherOutputStream initalEnCryptStream(OutputStream fos, byte[] key)
throws Exception
{
initalEnCrypt(key);
return new CipherOutputStream(fos, cipher);
}
public OutputStream getCipherOutputStream(OutputStream os, String contentId)
throws Exception
{
OutputStream cos = initalEnCryptStream(os, getKey(contentId));
return cos;
}
private long getAESCBCPaddingLength(long toBeEncryptLength)
{
long encryptLength = toBeEncryptLength + 16 - toBeEncryptLength % 16;
return encryptLength;
}
public long getSecretTextLengthForWhole(long plainTextLen)
{
long encryptLength = getAESCBCPaddingLength(plainTextLen);
// 第一项为加密的密文长度,第二项16为IV的字节数
long result = encryptLength + 16;
return result;
}
public long getSecretTextLengthForBlock(Long plainTextLen, Integer encryptBlockLength, Integer skipBlockLength)
{
long result = 0;
if (skipBlockLength != null && skipBlockLength > 0)
{
// 加密总次数
long times = plainTextLen / (encryptBlockLength + skipBlockLength);
// 需要加密的余数
long remainder = plainTextLen % (encryptBlockLength + skipBlockLength);
if (remainder > encryptBlockLength)
{
remainder = encryptBlockLength;
}
// 待加密的字节长度
long toBeEncryptLength = encryptBlockLength * (times) + remainder;
// 需要AES CBC PKCS5Padding加密的字节,加密后的长度
long encryptedLength = getAESCBCPaddingLength(toBeEncryptLength);
// 第一项为加密的密文长度,第二项为明文的长度,第三项16为IV的字节数
result = encryptedLength + (plainTextLen - toBeEncryptLength) + 16;
}
else
{
// 待加密的字节长度
long toBeEncryptLength = 0;
if (plainTextLen > encryptBlockLength)
{
toBeEncryptLength = encryptBlockLength;
}
else
{
toBeEncryptLength = plainTextLen;
}
// 需要AES CBC PKCS5Padding加密的字节,加密后的长度
long encryptedLength = getAESCBCPaddingLength(toBeEncryptLength);
// 第一项为加密的密文长度,第二项16为IV的字节数
result = encryptedLength + 16;
}
return result;
}
public void writeHeader(OutputStream os, String type, String contentId, Integer encryptBlockLength,
Integer encryptSkipLength)
throws Exception
{
String strContentType = contentType;
String strContentId = contentId;
os.write((byte)0x01);
os.write((byte)strContentType.getBytes().length);
os.write((byte)strContentId.getBytes().length);
os.write(strContentType.getBytes());
os.write(strContentId.getBytes());
long secretTextLength = 0;
if (ENCRYPT_METHOD_WHOLE.equals(type))
{
secretTextLength = getSecretTextLengthForWhole(plainTextLen);
}
else
{
secretTextLength = getSecretTextLengthForBlock(plainTextLen, encryptBlockLength, encryptSkipLength);
}
DCFHeader header = new DCFHeader();
header.setPlainTextLen(plainTextLen);
byte[] headerByte = header.toString().getBytes();
os.write(parseLong2Unitvar(headerByte.length));
os.write(parseLong2Unitvar(secretTextLength));
os.write(headerByte);
os.write(iv);
}
// 分段加密
public void encrypt4Block(String from, String to, String contentId, Integer encryptBlockLength,
Integer encryptSkipLength)
throws Exception
{
InputStream in = null;
OutputStream plainOutputStream = null;
OutputStream ciperOutputStream = null;
try
{
File file = new File(from);
in = new FileInputStream(file);
plainTextLen = file.length();
int maxStreamSize = (int)plainTextLen;
byte[] encryptBlock = new byte[encryptBlockLength];
byte[] skipBlock = null;
if (encryptSkipLength != null && encryptSkipLength > 0)
{
skipBlock = new byte[encryptSkipLength];
}
else
{
skipBlock = new byte[1024];
}
setIv();
plainOutputStream = new FileOutputStream(to);
ciperOutputStream = getCipherOutputStream(plainOutputStream, contentId);
writeHeader(plainOutputStream, ENCRYPT_METHOD_BLOCK, contentId, encryptBlockLength, encryptSkipLength);
boolean startWritePlainText = false;
int n = 0;
int total = 0;
while (true)
{
n = in.read(startWritePlainText ? skipBlock : encryptBlock);
if (n < 0)
{
break;
}
if (n > 0)
{
// 写入密文
if (!startWritePlainText)
{
// 照CBC模式,需要补全明文到16的倍数
int mode = n % 16;
int count = n / 16;
byte[] newEncryptBlock = new byte[(count + 1) * 16];
System.arraycopy(encryptBlock, 0, newEncryptBlock, 0, n);
if (mode == 0)
{
// 补全16个16
for (int i = 0; i < 16; i++)
{
newEncryptBlock[n + i] = (byte)16;
}
}
else
{
// 如mode等于13,就在后面补齐3个3
for (int i = 0; i < 16 - mode; i++)
{
newEncryptBlock[n + i] = (byte)(16 - mode);
}
}
ciperOutputStream.write(newEncryptBlock, 0, newEncryptBlock.length);
ciperOutputStream.flush();
startWritePlainText = true;
}
// 写入明文
else
{
plainOutputStream.write(skipBlock, 0, n);
plainOutputStream.flush();
if (encryptSkipLength != null && encryptSkipLength > 0)
{
startWritePlainText = false;
}
}
total += n;
}
if (total == maxStreamSize) // 读满最大长度则返回
{
break;
}
}
}
catch (Exception e)
{
throw e;
}
finally
{
if (plainOutputStream != null)
{
try
{
plainOutputStream.flush();
plainOutputStream.close();
}
catch (IOException e)
{
}
}
if (ciperOutputStream != null)
{
try
{
ciperOutputStream.flush();
ciperOutputStream.close();
}
catch (IOException e)
{
}
}
}
}
// 全文加密
public void encrypt4Whole(String from, String to, String contentId)
throws Exception
{
InputStream in = null;
OutputStream plainOutputStream = null;
OutputStream ciperOutputStream = null;
try
{
File file = new File(from);
in = new FileInputStream(file);
plainTextLen = file.length();
int maxStreamSize = (int)plainTextLen;
byte[] encriptBlock = new byte[1024];
setIv();
plainOutputStream = new FileOutputStream(to);
ciperOutputStream = getCipherOutputStream(plainOutputStream, contentId);
writeHeader(plainOutputStream, ENCRYPT_METHOD_WHOLE, contentId, null, null);
int n = 0;
int total = 0;
while (true)
{
n = in.read(encriptBlock);
if (n < 0)
{
break;
}
if (n > 0)
{
ciperOutputStream.write(encriptBlock, 0, n);
ciperOutputStream.flush();
total += n;
}
if (total == maxStreamSize) // 读满最大长度则返回
{
break;
}
}
}
catch (Exception e)
{
throw e;
}
finally
{
if (ciperOutputStream != null)
{
try
{
ciperOutputStream.flush();
ciperOutputStream.close();
}
catch (IOException e)
{
}
}
if (plainOutputStream != null)
{
try
{
plainOutputStream.flush();
plainOutputStream.close();
}
catch (IOException e)
{
}
}
}
}
public static byte[] getKey(String contentKey)
throws Exception
{
try
{
return getKey2(contentKey);
}
catch (Exception e)
{
throw e;
}
}
/**
* 根据contentKey生成key
*
* @param contentId 内容ID
* @throws Exception
* @return:key的byte[]
*/
public static byte[] getKey2(String contentKey)
throws Exception
{
String seed = "HUAWEIDRMtadfRkdfoa" + contentKey;
try
{
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sec = SecureRandom.getInstance("SHA1PRNG");
sec.setSeed(seed.getBytes());
kgen.init(128, sec);
Key key = kgen.generateKey();
return key.getEncoded();
}
catch (NoSuchAlgorithmException e)
{
throw e;
}
catch (IllegalStateException e)
{
throw e;
}
}
public static byte[] decryptCBC(byte[] src, byte[] iv, String contentId)
throws Exception
{
try
{
byte[] key = getKey(contentId);
SecretKeySpec keyspec = new SecretKeySpec(key, ALGORITHM_AES);
Cipher cipher = Cipher.getInstance(AES_CBC_PKCS5PADDING);
IvParameterSpec ivspec = new IvParameterSpec(iv);
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
return cipher.doFinal(src);
}
catch (Exception e)
{
throw e;
}
}
// 解密前128个字节
public void decrypt128Byte(String from, String to, String contentId)
throws Exception
{
RandomAccessFile file = null;
ByteArrayOutputStream baos = null;
OutputStream os = null;
try
{
file = new RandomAccessFile(from, "r");
int pos = 1;
byte b = 0;
long[] lArr = null;
// 获取内容类型长度
file.seek(pos);
b = file.readByte();
int contTypeLen = (int)b;
pos += 1;
// 获取内容ID长度
b = file.readByte();
int contIdLen = (int)b;
pos += 1;
// 获取头部长度
pos += contTypeLen + contIdLen;
file.seek(pos);
lArr = parseUnitvar2Long(file);
long headByteLen = lArr[0];
long headContLen = lArr[1];
// 获取加密块长度
lArr = parseUnitvar2Long(file);
long secretByteLen = lArr[0];
long secretContLen = lArr[1];
// 设置加密内容读取位置
pos += headByteLen + secretByteLen + headContLen;
file.seek(pos);
byte[] iv = getIv(file);
byte[] secretBytes = null;
byte[] plainBytes = null;
int i = 0;
int j = 0;
// 获取加密内容
baos = new ByteArrayOutputStream();
secretContLen = secretContLen - 16;
while (j < secretContLen && ((i = file.read()) != -1))
{
baos.write(i);
j++;
}
secretBytes = baos.toByteArray();
plainBytes = decryptCBC(secretBytes, iv, contentId);
os = new FileOutputStream(to);
os.write(plainBytes);
byte[] buff = new byte[1024];
while ((i = file.read(buff)) != -1)
{
os.write(buff, 0, i);
}
}
catch (Exception e)
{
throw e;
}
finally
{
if (baos != null)
{
try
{
baos.close();
}
catch (IOException e)
{
}
}
if (os != null)
{
try
{
os.flush();
os.close();
}
catch (IOException e)
{
}
}
if (file != null)
{
try
{
file.close();
}
catch (IOException e)
{
}
}
}
}
// 解密前128个字节
public void decrypt128Byte4Stream(String from, String to, String contentId)
throws Exception
{
RandomAccessFile file = null;
OutputStream os = null;
CipherOutputStream cos = null;
try
{
file = new RandomAccessFile(from, "r");
int pos = 1;
byte b = 0;
long[] lArr = null;
// 获取内容类型长度
file.seek(pos);
b = file.readByte();
int contTypeLen = (int)b;
pos += 1;
// 获取内容ID长度
b = file.readByte();
int contIdLen = (int)b;
pos += 1;
// 获取头部长度
pos += contTypeLen + contIdLen;
file.seek(pos);
lArr = parseUnitvar2Long(file);
long headByteLen = lArr[0];
long headContLen = lArr[1];
// 获取加密块长度
lArr = parseUnitvar2Long(file);
long secretByteLen = lArr[0];
long secretContLen = lArr[1];
// 设置加密内容读取位置
pos += headByteLen + secretByteLen + headContLen;
file.seek(pos);
byte[] iv = getIv(file);
byte[] key = getKey(contentId);
SecretKeySpec keyspec = new SecretKeySpec(key, ALGORITHM_AES);
Cipher cipher = Cipher.getInstance(AES_CBC_PKCS5PADDING);
IvParameterSpec ivspec = new IvParameterSpec(iv);
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
int i = 0;
int j = 0;
long k = 0;
int len = 1024;
os = new FileOutputStream(to);
cos = new CipherOutputStream(os, cipher);
byte[] bytes = new byte[len];
secretContLen = secretContLen - 16;
// 密文
while (j < secretContLen)
{
k = secretContLen - j;
if (k > len)
{
i = file.read(bytes);
}
else
{
i = file.read(bytes, 0, (int)k);
}
if (-1 != i)
{
cos.write(bytes, 0, i);
}
j = j + i;
}
// 明文
while ((i = file.read(bytes)) != -1)
{
os.write(bytes, 0, i);
}
}
catch (Exception e)
{
throw e;
}
finally
{
if (cos != null)
{
try
{
cos.flush();
cos.close();
}
catch (IOException e)
{
}
}
if (os != null)
{
try
{
os.flush();
os.close();
}
catch (IOException e)
{
}
}
if (file != null)
{
try
{
file.close();
}
catch (IOException e)
{
}
}
}
}
// 全文解密
public void decrypt4Whole(String path, String to, String contentId)
throws Exception
{
RandomAccessFile file = null;
ByteArrayOutputStream baos = null;
OutputStream os = null;
try
{
file = new RandomAccessFile(path, "r");
int pos = 1;
byte b = 0;
long[] lArr = null;
// 获取内容类型长度
file.seek(pos);
b = file.readByte();
int contTypeLen = (int)b;
pos += 1;
// 获取内容ID长度
b = file.readByte();
int contIdLen = (int)b;
pos += 1;
// 获取头部长度
pos += contTypeLen + contIdLen;
file.seek(pos);
lArr = parseUnitvar2Long(file);
long headByteLen = lArr[0];
long headContLen = lArr[1];
// 获取加密块长度
lArr = parseUnitvar2Long(file);
long secretByteLen = lArr[0];
long secretContLen = lArr[1];
// 设置加密内容读取位置
pos += headByteLen + secretByteLen + headContLen;
file.seek(pos);
// 获取加密内容
baos = new ByteArrayOutputStream();
byte[] iv = null;
byte[] secretBytes = null;
byte[] plainBytes = null;
int i = 0;
iv = getIv(file);
while ((i = file.read()) != -1)
{
baos.write(i);
}
secretBytes = baos.toByteArray();
plainBytes = decryptCBC(secretBytes, iv, contentId);
os = new FileOutputStream(to);
os.write(plainBytes);
}
catch (Exception e)
{
throw e;
}
finally
{
if (os != null)
{
try
{
os.flush();
os.close();
}
catch (IOException e)
{
}
}
if (baos != null)
{
try
{
baos.close();
}
catch (IOException e)
{
}
}
if (file != null)
{
try
{
file.close();
}
catch (IOException e)
{
}
}
}
}
// 分段解密
public void decrypt4Block(String from, String to, String contentId, Integer encryptBlockLength,
Integer encryptSkipLength)
throws Exception
{
RandomAccessFile file = null;
OutputStream os = null;
try
{
file = new RandomAccessFile(from, "r");
int pos = 1;
byte b = 0;
long[] lArr = null;
// 获取内容类型长度
file.seek(pos);
b = file.readByte();
int contTypeLen = (int)b;
pos += 1;
// 获取内容ID长度
b = file.readByte();
int contIdLen = (int)b;
pos += 1;
// 获取头部长度
pos += contTypeLen + contIdLen;
file.seek(pos);
lArr = parseUnitvar2Long(file);
long headByteLen = lArr[0];
long headContLen = lArr[1];
// 获取加密块长度
lArr = parseUnitvar2Long(file);
long secretByteLen = lArr[0];
long secretContLen = lArr[1];
// 设置加密内容读取位置
pos += headByteLen + secretByteLen + headContLen;
file.seek(pos);
byte[] iv = getIv(file);
secretContLen = secretContLen - 16;
os = new FileOutputStream(to);
decryptCore4Block(file,
os,
iv,
(int)getAESCBCPaddingLength(encryptBlockLength),
encryptSkipLength,
contentId);
}
catch (Exception e)
{
throw e;
}
finally
{
if (os != null)
{
try
{
os.flush();
os.close();
}
catch (IOException e)
{
}
}
if (file != null)
{
try
{
file.close();
}
catch (IOException e)
{
}
}
}
}
private void decryptCore4Block(RandomAccessFile file, OutputStream os, byte[] iv, int secretContentLen,
int encryptSkipLength, String contentId)
throws Exception
{
byte[] newIv = doDecrypt4Block(file, secretContentLen, os, iv, contentId);
if (newIv == null || newIv.length <= 0)
{
return;
}
int i = 0;
int j = 0;
while (j < encryptSkipLength && (i = file.read()) != -1)
{
os.write(i);
j++;
}
decryptCore4Block(file, os, newIv, secretContentLen, encryptSkipLength, contentId);
}
private byte[] doDecrypt4Block(RandomAccessFile file, long secretContentLen, OutputStream os, byte[] iv,
String contentId)
throws Exception
{
byte[] bytes = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try
{
int i = 0;
int j = 0;
while (j < secretContentLen && ((i = file.read()) != -1))
{
baos.write(i);
j++;
}
byte[] secretBytes = baos.toByteArray();
if (secretBytes != null && secretBytes.length > 0)
{
byte[] plainBytes = decryptCBC(secretBytes, iv, contentId);
bytes = new byte[16];
System.arraycopy(secretBytes, secretBytes.length - 16, bytes, 0, 16);
os.write(plainBytes);
}
}
catch (Exception e)
{
throw e;
}
finally
{
if (baos != null)
{
try
{
baos.flush();
baos.close();
}
catch (IOException e)
{
}
}
}
return bytes;
}
public void getKeyVal(String contentId)
{
try
{
String keyVal = new sun.misc.BASE64Encoder().encode(getKey(contentId));
System.out.println(keyVal);
}
catch (Exception e)
{
e.printStackTrace();
}
}
private class DCFHeader
{
protected final static String ENCRYPTION_METHOD = "Encryption-Method";
protected final static String Encryption_Method = "AES128CBC";
protected final static String PADDING = "padding";
protected final static String Padding_ID = "RFC2630";
protected final static String PLAINTEXTLEN = "plaintextlen";
protected long plainTextLen = 0;
protected final static String RIGHTS_ISSUER = "Rights-Issuer";
protected String rights_Issuer = "";
protected final static String CONTENT_NAME = "Content-Name";
protected String content_Name = "";
protected final static String CONTENT_DSCP = "Content-Description";
protected String content_Dscp = "";
protected final static String CONTENT_VENDOR = "Content_Vendor";
protected String content_Vendor = "";
protected final static String ICON_URI = "Icon-URI";
protected String icon_URI = "";
protected final static String OTHER = "Other-Header";
protected String other_Header = "";
protected final static String ENCRYPTLENGTH = "encryptlen";
protected final static String HWSKIP_BYTES = "HWSkipBytes";
protected String format;
public DCFHeader()
{
}
/**
* @return Returns the content_Dscp.
*/
public String getContent_Dscp()
{
return content_Dscp;
}
/**
* @param content_Dscp The content_Dscp to set.
*/
public void setContent_Dscp(String content_Dscp)
{
this.content_Dscp = content_Dscp;
}
/**
* @return Returns the content_Name.
*/
public String getContent_Name()
{
return content_Name;
}
/**
* @param content_Name The content_Name to set.
*/
public void setContent_Name(String content_Name)
{
this.content_Name = content_Name;
}
/**
* @return Returns the content_Vendor.
*/
public String getContent_Vendor()
{
return content_Vendor;
}
/**
* @param content_Vendor The content_Vendor to set.
*/
public void setContent_Vendor(String content_Vendor)
{
this.content_Vendor = content_Vendor;
}
/**
* @return Returns the icon_URI.
*/
public String getIcon_URI()
{
return icon_URI;
}
/**
* @param icon_URI The icon_URI to set.
*/
public void setIcon_URI(String icon_URI)
{
this.icon_URI = icon_URI;
}
/**
* @return Returns the plainTextLen.
*/
public long getPlainTextLen()
{
return plainTextLen;
}
/**
* @param plainTextLen The plainTextLen to set.
*/
public void setPlainTextLen(long plainTextLen)
{
this.plainTextLen = plainTextLen;
}
/**
* @return Returns the rights_Issuer.
*/
public String getRights_Issuer()
{
return rights_Issuer;
}
/**
* @param rights_Issuer The rights_Issuer to set.
*/
public void setRights_Issuer(String rights_Issuer)
{
this.rights_Issuer = rights_Issuer;
}
public String getFormat()
{
return format;
}
public String toString()
{
StringBuffer sb = new StringBuffer();
// Encryption-Method:AES128CBC
sb.append(ENCRYPTION_METHOD).append(": ").append(Encryption_Method);
// ;padding=RFC2630;plaintextlen=1079
sb.append(";").append(PADDING).append("=").append(Padding_ID);
if (plainTextLen >= 0) // plaintextlen=1079
{
sb.append(";").append(PLAINTEXTLEN).append("=").append(plainTextLen);
}
sb.append("\r\n");
// Rights-Issuer
if (StringUtils.isNotBlank(rights_Issuer))
{
sb.append(RIGHTS_ISSUER).append(": ").append(rights_Issuer).append("\r\n");
}
// Content-Name
if (StringUtils.isNotBlank(content_Name))
{
sb.append(CONTENT_NAME).append(": \"").append(content_Name).append("\"\r\n");
}
// Content-Description
if (StringUtils.isNotBlank(content_Dscp))
{
sb.append(CONTENT_DSCP).append(": \"").append(content_Dscp).append("\"\r\n");
}
// Content_Vendor
if (StringUtils.isNotBlank(content_Vendor))
{
sb.append(CONTENT_VENDOR).append(": \"").append(content_Vendor).append("\"\r\n");
}
// Icon-URI
if (StringUtils.isNotBlank(icon_URI))
{
sb.append(ICON_URI).append(": ").append(icon_URI).append("\r\n");
}
// other: copyright
if (StringUtils.isNotBlank(icon_URI))
{
sb.append(OTHER).append(": \"").append(other_Header).append("\"\r\n");
}
return sb.toString();
}
}
public static void main(String[] args)
throws Exception
{
TestEncode t = new TestEncode();
// t.decrypt128Byte("D:/test/测试DRM加密.txt.dcf", "D:/test/测试DRM加密(解密后).txt", "900000000006");
// t.decrypt128Byte4Stream("D:/test/测试DRM加密.txt.dcf", "D:/test/测试DRM加密(解密后).txt", "900000000006");
// t.decrypt128Byte4Stream("D:/test/img1.jpg.dcf", "D:/test/img1(解密后).jpg", "CNBJTW2600000016224");
//t.encrypt4Block("E:/mypic/cc.jpg", "E:/encodepic/jm.jpg.dcf", "900000000006", 128, 128);
t.decrypt4Block("E:/encodepic/jm.jpg.dcf", "E:/mypic/jiemi.jpg", "900000000006", 128, 128);
}
}