linux查看文件的加密方式,用标志位判别法对linux文件的内容进行简单加密

对于加密我是个外行,特别是相对于加密解密、信息安全专业的大虾们来说,我更算是屌丝。本文重点不是在加密的算法,重点是在对linux文件的内容进行加密的这种原理和流程以及思想,望各位高手不要见笑哦~

文件内容加密,并非文件加密,是把我们需要对内容加密的文件,在由系统调用write()写入后,读出来的加密后的密文;要解密后才能重现原来的内容。

闲话少说,直接开始吧:

首先,要强调的是,我们只是对我们需要的文件加密,而非对系统中所有文件加密,所以呢...要标志出这些我们需要加密的文件。那么,选择什么作为标记呢?

要知道,我们在操作一个文件时,最终要操作的是一个称作inode的i节点对象(注意了哦,这个对象是在内存中滴。),而在咱们的硬件设备上真正存在一个文件i节点这个i节点对象相对应,在打开文件的时候内存中的i节点对象的一部分信息就是由硬件设备上的真正的文件i节点的信息来填充的。要想创建加密标志,这个标志当然也要写到硬件设备上,也就是真正的i节点中去(不然写到内存里的结构中,一掉电,标志位就没了)。经过一番挑选,选择了inode对象中的i_flags元素来保存这个加密标志位,而没有选择另外一个元素i_mode(原因下面会简单提到);这里i_flags元素的0~10位已经被使用,而第11位未被使用。所以可以采用这一位来作加密标记。

标记位找到了,下面我们来看看怎么把要创建的加密文件的加密标记打到inode对象中。

我们知道在linux下创建一个文件时,open()系统调用实际上已经取代了系统调用write()系统调用(深入到源码中sys_open其实在某些条件下跳转、调用的是sys_write())。所以,我们要在open()系统调用里找答案。

而利用open()系统调用创建文件时,会有三个参数

open(const char*pathname,int oflag,),

如果oflag标志启用了O_CREAT位时,那么需要第三个参数mode。注意,这里面的参数oflag和mode并不是直接写入到inode中的,mode要经过一定的处理后才写入到inode对象的i_mode元素中;而参数oflag根本不会写入到inode的i_flag中。而参数mode其所有正常的标志都已经被占用,剩下的标志若是被启用会创建出linux无法识别的古怪文件,当然我们也就无法对其读写;而参数oflag就有比较多的“空闲”位可以被我们利用,这里选取的是第四位----这里最好把这个标志位定义成宏,方便操作也比较规范,所以,接下来......

定义我们的加密标志常量O_CODE:

这里会比较麻烦一点,因为好多地方都包含有open()的参数oflag的常量。一个一个来:

/usr/include/asm/fcntl.h、/usr/include/bits/fcntl.h、/源码目录树/include/asm-i386/fcntl.h中都得加上这么一个宏定义:#define

O_CODE 4。好了,这样就可以深入内核里面,看看open是怎么创建一个inode的,我们要投机取巧,因地制宜的把这个启用了O_CODE的oflag参数标记到inode对象中。

分析源码:

==================== fs/open.c ====================

asmlinkage longsys_open(const char * filename, int flags, int mode)

{

.......//这里只给出相关的关键源码

fd =get_unused_fd();

if (fd >= 0) {

struct file *f =filp_open(tmp, flags, mode);//从这个函数跟下去

.......

}

==================== fs/open.c====================

struct file *filp_open(const char * filename, int flags, int mode)

{

int namei_flags, error;

struct nameidata nd;

namei_flags = flags;//有木有,这个标志传给了 namei_flags ,我们一定要盯紧参数flags哦。

if ((namei_flags+1) & O_ACCMODE)

namei_flags++;

if (namei_flags & O_TRUNC)

namei_flags |= 2;

error =open_namei(filename, namei_flags, mode, &nd);

if (!error)

returndentry_open(nd.dentry, nd.mnt, flags);

return ERR_PTR(error);

}

//接着跟下去

==================== fs/namei.c====================

intopen_namei(const char * pathname, int flag, int mode, struct nameidata *nd)

{

int acc_mode, error = 0;

struct path path;

struct dentry *dir;........

nd->intent.open.flags = flag;//看到没有,flag存到nd里面去了 nd->intent.open.create_mode

= mode;

.....

//诶,path_lookup(),这个函数厉害咯,大家注意咯,载着flag的nd成为参数咯。

error = path_lookup(pathname,

LOOKUP_PARENT|LOOKUP_OPEN|LOOKUP_CREATE,

nd); if (error)

return error;

.......

dir = nd->dentry;

.......

//注意了,这里要开始创建文件咯,这一步很关键

error = vfs_create(dir->d_inode,

path.dentry, mode, nd);

}

==================== fs/namei.c====================

int vfs_create(struct inode *dir,

struct dentry *dentry, int mode, struct nameidata

*nd)

{

....

error = dir->i_op->create(dir,

dentry, mode, nd);//这里有一个跳跃,dir是struct inode

*类型,调用//dir->i_op->create()时,其实调用的是static

int ext3_create (struct inode * dir, struct dentry * dentry, int

mode,struct

//nameidata *nd)

return error;

}

==================== fs/ext3/namei.c====================

static int ext3_create (struct inode * dir, struct dentry * dentry,

int mode, struct nameidata *nd)

{....

//这里通过 ext3_new_inode

()创建一个i节点,注意哦,nd跟着传下来了哦,nd里可保存着有咱们的oflag哦

//因为 ext3_new_inode

没有传进我们的nd,那我们为了把nd保存的标志传递进inode,这里需要把nd中保存的oflag

//传到dir中,具体做法如下:

inode = ext3_new_inode (handle, dir, mode);

....

}

==================== fs/ext3/ialloc.c====================

struct inode *ext3_new_inode(handle_t

*handle, struct inode * dir, int mode)

{

//下面这段代码是我加的,设置一个标志,用以标记open是否要创建一个code文件

......

......

ext3_set_inode_flags(inode);//终于到了我们的重点了

....

}

==================== fs/ext3/inode.c====================

void ext3_set_inode_flags(struct inode *inode)

{

unsigned int flags =

EXT3_I(inode)->i_flags;

inode->i_flags &=

~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC);

.....

然后就是要修改write()的系统调用了,根据inode的标志来判断是要写进去密文呢还是原文:

==================== fs/read_write.c====================

asmlinkage ssize_t sys_write(unsigned int fd, const char __user *

buf, size_t count)

{

struct file *file;

ssize_t ret = -EBADF;

int fput_needed;

file = fget_light(fd,

&fput_needed);

if (file) {

loff_t pos =

file_pos_read(file);

ret = vfs_write(file,

buf, count, &pos);

....

}

然后,编译内核....重启。

编译、重启成功后,就可以写测试函数,写一个测试函数,测试

#include

#include

#include

#include

#include

#include

#include

int main(int ar1,char*ar2[])

{

int lenth;

int fd;

lenth=strlen(ar2[1]);

char

*buf=(char*)malloc(lenth*sizeof(char));

strcpy(buf,ar2[1]);

fd=open("/home/file.log",O_APPEND|O_CREAT|O_RDWR|O_CODE,0777);

write(fd,buf,lenth);

close(fd);

return 0;

}

编译,运行,测试结果.....

~~ok,终于大功告成。(注意:我用的内核是2.6.13)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值