前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用AES进行文件加密算法

使用AES进行文件加密算法

作者头像
Xiaolei123
修改2022-06-19 13:59:16
3.4K0
修改2022-06-19 13:59:16
举报
文章被收录于专栏:肖蕾的博客

使用AES进行文件加密算法

前言:最近想对手机上一些文件进行加密隐藏,想自己基于jvm平台写一个(kotlin/java)但是网上的加密算法都是不公开的,所以自己利用AES的算法整出了一个文件加密解密的工具 注意:因为我电脑上的JDK是12+,所以如果移植到安卓上有出现报错,是正常现象,只需要修改 AESEncoder 文件就好了

FileEncoder.kt

代码语言:text
复制
import java.io.Closeable
import java.io.File
import java.io.RandomAccessFile
import java.lang.StringBuilder
/** * 文件加密 * 注意!!千万不可以使用多线程来同时加密/解密多个文件 */
class FileEncoder(passwd: String,val debug: Boolean = true, bufferSize: Int = (1024 * 1024 * 1)) : Closeable
{    
    private val aesEncoder = AESEncoder(passwd)    
    private val buffer = ByteArray(bufferSize)    
    private val spliteStr = "|"    
    /**     * 加密算法     * [msgLen | encode_file | msg]     */    
    fun encode(src: File, e_file: File, process: (process: Float) -> Unit)    
    {        
        val srcLen = src.length().toFloat()        
        val fis = src.inputStream()        
        val accessFile = RandomAccessFile(e_file, "rw")        
        // 这里在文件顶部写入8位的占位符        
        var msgLen = 0L        
        val headBytes = long2Bytes(msgLen)        
        accessFile.write(headBytes)        
        log("写入头部信息")        
        val msgBuilder = StringBuilder()        
        var readLen = fis.read(buffer)        
        var readCount = 0L        
        while (readLen > 0)        
        {            
            readCount += readLen            
            val encodeArray = aesEncoder.encode(buffer, readLen)            
            msgBuilder.append(encodeArray.size).append(spliteStr)            
            accessFile.write(encodeArray)            
            process.invoke(readCount / srcLen)            
            readLen = fis.read(buffer)        
        }        
        val msg = msgBuilder.toString()        
        msgBuilder.setLength(0)        
        log(msg)        
        // 将尾部信息转换成字节数组        
        val msgByteArry = msg.toByteArray()        
        // 将尾部信息字节数组,加密        
        val msgEncodeByteArray = aesEncoder.encode(msgByteArry, msgByteArry.size)        
        // 写入加密尾部信息        
        accessFile.write(msgEncodeByteArray)        
        log("写入加密尾部信息")        
        // 测量出加密后的信息长度是多少        
        msgLen = msgEncodeByteArray.size.toLong()        
        log("新的长度:$msgLen")        
        // 将光标移动到文件头,复写信息        
        accessFile.seek(0)        
        // 重新将长度写入进去        
        accessFile.write(long2Bytes(msgLen))        
        fis.close()        
        accessFile.close()    
    }    
    /**     * 解密算法     */    
    fun decode(src: File, d_file: File, process: (process: Float) -> Unit)    
    {        
        val buffer: ByteArray        
        val raf = RandomAccessFile(src, "r")        
        val fos = d_file.outputStream()        
        val headBytes = ByteArray(8)        
        val headLen = raf.read(headBytes)        
        if (headLen != 8)        
        {            
            raf.close()            
            fos.close()            
            return        
        }        
        val msgLen = bytes2Long(headBytes)        
        log("解密:$msgLen")        
        val srcLen = src.length()        
        val msgByteArray = ByteArray(msgLen.toInt())        
        // 将光标移动到尾部,读取信息        
        raf.seek(srcLen - msgLen)        
        val readMsgLen = raf.read(msgByteArray)        
        log("已读取信息长度:$readMsgLen")        
        val decodeMsgArray = aesEncoder.decode(msgByteArray, msgByteArray.size)        
        val decodeMsg = String(decodeMsgArray)        
        log(decodeMsg)        
        val msgs = decodeMsg.split(spliteStr).dropLastWhile { it.isEmpty() }        
        val msgLong = msgs.map { it.toLong() }        
        val maxBufferSize = msgLong.max() ?: 0        
        buffer = ByteArray(maxBufferSize.toInt())        
        log(msgLong)        
        // 将光标回到读取完头部信息的位置        
        raf.seek(8)        
        msgLong.forEachIndexed { index, len ->            
                raf.read(buffer, 0, len.toInt())            
                val encodeArray = aesEncoder.decode(buffer, len.toInt())            
                fos.write(encodeArray)            
                process.invoke(index.toFloat() / msgLong.size)        
        }        
        process.invoke(1f)        
        fos.flush()        
        fos.close()    
    }    
    /**     * 长整型转换成字节数组     */    
    private fun long2Bytes(num: Long): ByteArray    
    {        
        val byteNum = ByteArray(8)        
        for (ix in 0..7)        
        {            
            val offset = 64 - (ix + 1) * 8            
            byteNum[ix] = (num shr offset and 0xff).toByte()        
        }        
        return byteNum    
    }    
    /**     * 字节数组转换成长整型     */    
    private fun bytes2Long(byteNum: ByteArray): Long    
    {        
        var num: Long = 0        
        for (ix in 0..7)        
        {            
            num = num shl 8            
            num = num or (byteNum[ix].toInt() and 0xff).toLong()        
        }        
        return num    
    }    
    private inline fun log(msg: Any?)    
    {        
        if (debug)        
        {            
            println(msg)        
        }    
    }    
    override fun close()    
    {        
        aesEncoder.close()    
    }
}

AESEncoder.kt

代码语言:javascript
复制
import java.io.Closeable
import java.security.SecureRandom
import java.util.*
import javax.crypto.Cipher
import javax.crypto.KeyGenerator
import javax.crypto.spec.SecretKeySpec
/* * AES对称加密和解密 */
class AESEncoder(encodeRules: String) : Closeable
{    
    private val encoder = Base64.getEncoder()   
    private val decoder = Base64.getDecoder()    
    private var encodeCipher: Cipher    
    private var decoderCipher: Cipher    
    private val bufferHolder = LinkedHashMap<Int, ByteArray>()    
    init    
    {        
        //1.构造密钥生成器,指定为AES算法,不区分大小写        
        val keygen = KeyGenerator.getInstance("AES")        
        //2.根据ecnodeRules规则初始化密钥生成器        
        //生成一个128位的随机源,根据传入的字节数组        
        keygen.init(128, SecureRandom(encodeRules.toByteArray()))        
        //3.产生原始对称密钥        
        val original_key = keygen.generateKey()        
        //4.获得原始对称密钥的字节数组        
        val raw = original_key.encoded        
        //5.根据字节数组生成AES密钥        
        val key = SecretKeySpec(raw, "AES")        
        //6.根据指定算法AES自成密码器        
        encodeCipher = Cipher.getInstance("AES")        
        decoderCipher = Cipher.getInstance("AES")       
        //7.初始化密码器,第一个参数为加密(Encrypt_mode)或者解密解密(Decrypt_mode)操作,第二个参数为使用的KEY        
        encodeCipher.init(Cipher.ENCRYPT_MODE, key)        
        //7.初始化密码器,第一个参数为加密(Encrypt_mode)或者解密(Decrypt_mode)操作,第二个参数为使用的KEY        
        decoderCipher.init(Cipher.DECRYPT_MODE, key)    
    }    
    /*     * 加密     * 1.构造密钥生成器     * 2.根据ecnodeRules规则初始化密钥生成器     * 3.产生密钥     * 4.创建和初始化密码器     * 5.内容加密     * 6.返回字符串     */    
    fun encode(content: ByteArray, len: Int): ByteArray   
    {        
        var buffer = bufferHolder[len]        
        if (buffer == null)        
        {            
            buffer = ByteArray(len)            
            bufferHolder[len] = buffer        
        }        
        System.arraycopy(content, 0, buffer, 0, len)        
        //8.获取加密内容的字节数组(这里要设置为utf-8)不然内容中如果有中文和英文混合中文就会解密为乱码        
        val byte_encode = buffer        
        //9.根据密码器的初始化方式--加密:将数据加密        
        val byte_AES = encodeCipher.doFinal(byte_encode)        
        //10.将加密后的数据转换为字符串        
        //这里用Base64Encoder中会找不到包        
        //解决办法:        //在项目的Build path中先移除JRE System Library,再添加库JRE System Library,重新编译后就一切正常了。        
        //11.将字符串返回        
        return encoder.encode(byte_AES)    
    }    
    /*     * 解密     * 解密过程:     * 1.同加密1-4步     * 2.将加密后的字符串反纺成byte[]数组     * 3.将加密内容解密     */    
    fun decode(content: ByteArray, len: Int): ByteArray    
    {        
        var buffer = bufferHolder[len]        
        if (buffer == null)        
        {            
            buffer = ByteArray(len)            
            bufferHolder[len] = buffer        
        }        
        System.arraycopy(content, 0, buffer, 0, len)        
        //8.将加密并编码后的内容解码成字节数组        
        val byte_content = decoder.decode(buffer)        
        /*         * 解密         */        
        val byte_decode = decoderCipher.doFinal(byte_content)        
        return byte_decode    
    }    
    override fun close()    
    {        
        bufferHolder.clear()    
    }
}

效果

右边是加密后的文件,左边是解密后的文件

老群被封,+新Q群709287944

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-5-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 使用AES进行文件加密算法
    • 效果
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档