【python】 AES 加密
【python】 AES 加密
ok绷forever 发表于6个月前
【python】 AES 加密
  • 发表于 6个月前
  • 阅读 13
  • 收藏 0
  • 点赞 0
  • 评论 0

腾讯云 技术升级10大核心产品年终让利>>>   

工具:

  • crypto python 提供的加密库

  • python 2.7.10

本文采用 AES 对文件进行加密,采用CBC模式

因为 AES 是块加密,每 16 字节进行一次加密

采用 lambda 实现对文件分块,不足 16 字节 的用 空格补齐。

代码如下:

#! -*- coding:utf-8 -*-
from Crypto.Cipher import AES
import random
import string
from Crypto import Random
import binascii
import sys
import re
from binascii import b2a_hex, a2b_hex  


PADDING = '\0'   
pad_it = lambda s: s+(16 - len(s)%16)*PADDING

# iv 是AES加密的初始密钥向量 key 是密钥 
# 加密函数
def string_normal(s,key,iv):
        s = pad_it(s)
        cryptor = AES.new(key,AES.MODE_CBC,iv)
        sum = ''
# 加密的内容必须是16的倍数,如果不是就用pad_it() 函数补全
        for ii in range(len(s)/16):
            sum = sum + b2a_hex(cryptor.encrypt(s[ii*16:ii*16+16]))
#因为AES加密时候得到的字符串不一定是ascii字符集的,输出到终端或者保存时候可能存在问题
#所以这里统一把加密后的字符串转化为16进制字符串
        return sum

# 解密
def decrypt(text,key,iv):  
    cryptor = AES.new(key,AES.MODE_CBC, iv)  
#将 16进制字符串转化为二进制字符串再进行解密
    plain_text  = cryptor.decrypt(a2b_hex(text))  
    return plain_text

由于采用的是 生成的密钥是 16 位,所以采用随机生成 16 位的密钥信息, 代码如下:

    """
    生成长度16的随机数密码
    """
    def gen_random_key(length):
        # 随机出数字的个数
        numOfNum = random.randint(1,length-1)
        numOfLetter = length - numOfNum

        # 选中numOfNum个数字
        selectNum = [random.choice(string.digits) for i in range(numOfNum)]

        # 选中numOfLetter个字母
        selectLetter = [random.choice(string.ascii_letters) for i in range(numOfLetter)]

        # 打乱这个组合
        slcChar = selectNum + selectLetter
        random.shuffle(slcChar)
        # 生成密码
        genKey = ''.join([i for i in slcChar])
        return genKey

使用 python 加密 ,java 解密代码如下:

package com.ben.restjpademo;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.util.ArrayList;

import javax.annotation.Resource;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
import org.junit.Test;

import sun.misc.BASE64Decoder;

import com.ben.restjpademo.dao.JobRepository;
import com.ben.restjpademo.dao.JobspiderReposity;
import com.ben.restjpademo.dao.KeymngRepository;
import com.ben.restjpademo.domain.Job;
import com.ben.restjpademo.domain.Keymng;

import javax.xml.bind.DatatypeConverter;

public class TestHadoop {	
	/*
	 *  20170601 读取hadoop中的文件
	 */
	@Test
	public void getfile() throws IOException{
		String uri = "hdfs://192.168.17.30:9000";
		Configuration config = new Configuration();
		FileSystem fs = FileSystem.get(URI.create(uri),config);
		
		// 列出 hdfs 上的 /source 目录下的所有文件和目录
		FileStatus[] statuses = fs.listStatus(new Path("/source"));
		for(FileStatus status : statuses){
			System.out.println(status);
		}
		
		// 显示在 hdfs 上/source下指定文件的内容
		OutputStream os = new ByteArrayOutputStream();
		
		String content = "";
		
		InputStream is = fs.open(new Path("/source/www.sina.com.cn/www.sina.com.cn.txt"));
		IOUtils.copyBytes(is,os,1024, true);
		
		content = os.toString();
		byte[] b = content.getBytes();
                # 将 python 加密的 16 进制字符串转化为 2 进制
		byte[] bytes = DatatypeConverter.parseHexBinary(content);
		System.out.println("加密文件:");
		System.out.println(content.length());	
		System.out.println(bytes);
		this.padding(bytes);
	}
	  
	
	public void padding(byte[] s){
		String key = "XCwX56kd6AYAhnlc";
		String iv = "KnYpyHyGJtR5nFkx";
		try{		
                       Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
                       SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
                        IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
                        cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
                        byte[] original = cipher.doFinal(s);
                        String originalString = new String(original);
            
                        System.out.println("解密文件:");
                        System.out.println(originalString);
        	        FileOutputStream out = null;
                        try{
    			    out = new FileOutputStream(new File("E:/storge.html")); 
    			    out.write(originalString.getBytes());
    			    out.close();
    		        }catch(IOException e){
    			    e.printStackTrace();
    		        }

		}catch(Exception e){
			e.printStackTrace();
		}
	}
}

共有 人打赏支持
粉丝 4
博文 114
码字总数 53609
×
ok绷forever
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: