java实现文件加密与解密

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);
    }
    
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值