目的:
一、部分私人文件不想让别人看到, Linux下又不能用Windows上的加解密工具 (也许有现成的东西, 只是我自己不知道吧, 不过也懒得搜了)
二、最近再看APUE, 写点代码当实践与复习 (发现又开始忘了)
算法:
文件字节与密钥顺序进行异或
功能:
一、对指定文件加密或解密
二、对指定文件夹中所有文件加密或解密
缺陷:
一、单个文件必须小于2G
二、由于是直接在文件上做修改, 故而可能因为某些特殊原因(停电等造成的程序非正常终止)致使文件被破坏
一、部分私人文件不想让别人看到, Linux下又不能用Windows上的加解密工具 (也许有现成的东西, 只是我自己不知道吧, 不过也懒得搜了)
二、最近再看APUE, 写点代码当实践与复习 (发现又开始忘了)
算法:
文件字节与密钥顺序进行异或
功能:
一、对指定文件加密或解密
二、对指定文件夹中所有文件加密或解密
缺陷:
一、单个文件必须小于2G
二、由于是直接在文件上做修改, 故而可能因为某些特殊原因(停电等造成的程序非正常终止)致使文件被破坏
注意:
如果忘了密钥, 猜测时一定要注意, 比如用XXX解密, 发现没解密出原始数据, 记得要再用一次XXX解密成猜测前的状态
#include <stdio.h>
#include <fcntl.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>
#define PWD_MAX_LEN (64)
int
encry_file(const char * filename, const char * password, int pwdlen)
{
int i;
int n;
int filedes;
long position;
char buffer[BUFSIZ];
char cwd[PATH_MAX + 1];
if (getcwd(cwd, PATH_MAX + 1) == NULL) {
printf("getcwd error\n");
exit(127);
}
if ((filedes = open(filename, O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO)) == -1) {
printf("open failed for \"%s/%s\"\n", cwd, filename);
exit(127);
}
position = 0;
while ((n = read(filedes, buffer, BUFSIZ)) > 0) {
for (i = 0; i < n; ++i) {
buffer[i] ^= password[n % pwdlen];
}
lseek(filedes, position, SEEK_SET);
if (write(filedes, buffer, n) != n) {
printf("write error for \"%s/%s\"\n", cwd, filename);
exit(127);
}
position += n;
}
if (n < 0) {
printf("read error for \"%s/%s\"\n", cwd, filename);
exit(127);
}
close(filedes);
return 0;
}
int
encry_dir(const char * dirname, const char * password, int pwdlen)
{
DIR * dp;
struct dirent * dirp;
struct stat statbuf;
char cwd[PATH_MAX + 1];
if ((dp = opendir(dirname)) == NULL) {
printf("opendir failed for \"%s/%s\"\n", cwd, dirname);
exit(127);
}
while ((dirp = readdir(dp)) != NULL) {
if (strcmp(dirp->d_name, ".") == 0 ||
strcmp(dirp->d_name, "..") == 0) {
continue;
}
if (getcwd(cwd, PATH_MAX + 1) == NULL) {
printf("getcwd error\n");
exit(127);
}
if (chdir(dirname) == -1) {
printf("chdir error for \"%s\"\n", dirname);
exit(127);
}
if (lstat(dirp->d_name, &statbuf) == -1) {
printf("lstat failed for \"%s/%s\"\n", cwd, dirp->d_name);
exit(127);
}
if (S_ISREG(statbuf.st_mode)) {
encry_file(dirp->d_name, password, pwdlen);
}
else if (S_ISDIR(statbuf.st_mode)) {
encry_dir(dirp->d_name, password, pwdlen);
}
if (chdir(cwd) == -1) {
printf("chdir error for \"%s\"\n", cwd);
exit(127);
}
}
closedir(dp);
return 0;
}
int
main(void)
{
int i;
int pwdlen;
char * p;
char filename[PATH_MAX];
char pathname[PATH_MAX + 1];
char password[PWD_MAX_LEN];
char pwdcheck[PWD_MAX_LEN];
char cwd[PATH_MAX + 1];
struct stat statbuf;
printf("input file/directory name:\n");
if (fgets(pathname, PATH_MAX + 1, stdin) == NULL) {
printf("fgets error\n");
exit(127);
}
i = strlen(pathname);
assert(i >= 1);
if (pathname[i - 1] == '\n') {
pathname[i - 1] = '\0';
}
if (lstat(pathname, &statbuf) == -1) {
printf("lstat failed for \"%s\"\n", pathname);
exit(127);
}
printf("input password:\n");
scanf("%s", password);
printf("input password again:\n");
scanf("%s", pwdcheck);
password[sizeof(password) - 1] = '\0';
pwdcheck[sizeof(pwdcheck) - 1] = '\0';
pwdlen = strlen(password);
if (pwdlen == 0 || strcmp(password, pwdcheck) != 0) {
printf("password error\n");
exit(127);
}
if (getcwd(cwd, PATH_MAX + 1) == NULL) {
printf("getcwd error\n");
exit(127);
}
if (S_ISREG(statbuf.st_mode)) {
if ((p = strrchr(pathname, '/')) != NULL) {
strcpy(filename, ++p);
*p = '\0';
}
else {
strcpy(filename, pathname);
strcpy(pathname, cwd);
}
if (chdir(pathname) == -1) {
printf("chdir error for \"%s\"\n", pathname);
exit(127);
}
encry_file(filename, password, pwdlen);
if (chdir(cwd) == -1) {
printf("chdir error for \"%s\"\n", cwd);
exit(127);
}
}
else if (S_ISDIR(statbuf.st_mode)) {
if (chdir(pathname) == -1) {
printf("chdir error for \"%s\"\n", pathname);
exit(127);
}
encry_dir(".", password, pwdlen);
if (chdir(cwd) == -1) {
printf("chdir error for \"%s\"\n", cwd);
exit(127);
}
}
else {
printf("no file need to encry\n");
}
exit(0);
}