#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0400
#endif
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <windows.h>
#include <wincrypt.h>
#define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
#define KEYLENGTH 0x00800000
void HandleError(char *s);
HCRYPTPROV GetCryptProv();
#define ENCRYPT_ALGORITHM CALG_RC4
#define ENCRYPT_BLOCK_SIZE 8
BOOL EncryptFile(
PCHAR szSource,
PCHAR szDestination,
PCHAR szPassword);
HCRYPTKEY GenKeyByPassword(HCRYPTPROV hCryptProv,PCHAR szPassword);
HCRYPTKEY GenKeyByRandom(HCRYPTPROV hCryptProv,FILE* hDestination);
//-------------------------------------------------------------------
// Begin main.
void main(void)
{
PCHAR szSource;
PCHAR szDestination;
CHAR szPassword[100] = “”;
char response;
if(!(szSource=(char *)malloc(100)))
HandleError(“Memory allocation failed.”);
if(!(szDestination=(char *)malloc(100)))
HandleError(“Memory allocation failed.”);
printf(“加密一个文件. \n\n”);
printf("请输入需要被加密文件的名称: ");
fgets(szSource, 100, stdin);
if(szSource[strlen(szSource)-1] == ‘\n’)
szSource[strlen(szSource)-1] = ‘\0’;
printf("请输入需要输出文件文件的名称: ");
fgets(szDestination, 100, stdin);
if(szDestination[strlen(szDestination)-1] == ‘\n’)
szDestination[strlen(szDestination)-1] = ‘\0’;
printf("要使用密码对这个文件加密吗? ( y/n ) ");
response = getchar();
if(response == ‘y’)
{
printf(“请输入密码:”);
getchar();
gets(szPassword);
}
else
{
printf(“密钥将生成但没有使用密码. \n”);
}
//-------------------------------------------------------------------
// 调用函数 EncryptFile 进行实际的加密操作.
if(EncryptFile(szSource, szDestination, szPassword))
{
printf(“对文件 %s 的加密已经成功! \n”,
szSource);
printf(“加密后的数据存储在文件 %s 中.\n”,szDestination);
}
else
{
HandleError(“解密文件出错!”);
}
//-------------------------------------------------------------------
// 释放内存.
if(szSource)
free(szSource);
if(szDestination)
free(szDestination);
} // end main
//-------------------------------------------------------------------
// 功能:加密原文szSource文件,加密后的数据存储在szDestination文件中
// 参数:
// szSource:原文文件名
// szDestination:加密后数据存储文件
// szPassword:用户输入的密码
static BOOL EncryptFile(
PCHAR szSource,
PCHAR szDestination,
PCHAR szPassword)
{
//-------------------------------------------------------------------
// 变量申明与初始化.
FILE *hSource;
FILE *hDestination;
HCRYPTPROV hCryptProv;
HCRYPTKEY hKey;
PBYTE pbBuffer;
DWORD dwBlockLen;
DWORD dwBufferLen;
DWORD dwCount;
//-------------------------------------------------------------------
// 打开原文文件.
if(hSource = fopen(szSource,“rb”))
{
printf(“原文文件 %s 已经打开. \n”, szSource);
}
else
{
HandleError(“打开原文文件出错!”);
}
//-------------------------------------------------------------------
// 打开目标文件.
if(hDestination = fopen(szDestination,“wb”))
{
printf(“目标文件 %s 已经打开. \n”, szDestination);
}
else
{
HandleError(“打开目标文件出错!”);
}
//获取加密服务者句柄
hCryptProv = GetCryptProv();
//-------------------------------------------------------------------
// 创建会话密钥.
if(!szPassword || strcmp(szPassword,“”)==0 )
{
//--------------------------------------------------------------
// 当输入密码为空时,则创建随机的加密密钥,并导出创建的密钥保存到文件中.
hKey = GenKeyByRandom( hCryptProv, hDestination);
}
else
{
//--------------------------------------------------------------
// 当输入密码不为空时,则通过输入密码创建加密密钥
hKey=GenKeyByPassword( hCryptProv, szPassword);
}
//--------------------------------------------------------------------
// 因为加密算法按ENCRYPT_BLOCK_SIZE 大小块加密,所以被加密的
// 数据长度必须是ENCRYPT_BLOCK_SIZE 的整数倍。下面计算一次加密的
// 数据长度。
dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE;
//--------------------------------------------------------------------
// 确定加密后密文数据块大小. 若是分组密码模式,则必须有容纳额外块的空间
if(ENCRYPT_BLOCK_SIZE > 1)
dwBufferLen = dwBlockLen + ENCRYPT_BLOCK_SIZE;
else
dwBufferLen = dwBlockLen;
//-------------------------------------------------------------------
// 分配内存空间.
if(pbBuffer = (BYTE *)malloc(dwBufferLen))
{
printf(“已经为缓冲区分配了内存. \n”);
}
else
{
HandleError(“所需内存不够. \n”);
}
//-------------------------------------------------------------------
// 循环加密 原文件
do
{
//-------------------------------------------------------------------
// 每次从原文件中读取dwBlockLen字节数据.
dwCount = fread(pbBuffer, 1, dwBlockLen, hSource);
if(ferror(hSource))
{
HandleError(“读取明文文件出错!\n”);
}
//-------------------------------------------------------------------
// 加密数据.
if(!CryptEncrypt(
hKey, //密钥
0, //如果数据同时进行散列和加密,这里传入一个散列对象
feof(hSource), //如果是最后一个被加密的块,输入TRUE.如果不是输入FALSE.
//这里通过判断是否到文件尾来决定是否为最后一块。
0, //保留
pbBuffer, //输入被加密数据,输出加密后的数据
&dwCount, //输入被加密数据实际长度,输出加密后数据长度
dwBufferLen)) //pbBuffer的大小。
{
HandleError(“Error during CryptEncrypt. \n”);
}
//-------------------------------------------------------------------
// 把加密后数据写到密文文件中
fwrite(pbBuffer, 1, dwCount, hDestination);
if(ferror(hDestination))
{
HandleError(“写入密文时出错.”);
}
} while(!feof(hSource));
//-------------------------------------------------------------------
// 关闭文件
if(hSource)
{
if(fclose(hSource))
HandleError(“关闭原文文件出错!”);
}
if(hDestination)
{
if(fclose(hDestination))
HandleError(“关闭目标文件出错!”);
}
//-------------------------------------------------------------------
// 释放内存空间.
if(pbBuffer)
free(pbBuffer);
//-------------------------------------------------------------------
// 销毁会话密钥
if(hKey)
{
if(!(CryptDestroyKey(hKey)))
HandleError(“Error during CryptDestroyKey”);
}
//-------------------------------------------------------------------
// 释放CSP句柄
if(hCryptProv)
{
if(!(CryptReleaseContext(hCryptProv, 0)))
HandleError(“Error during CryptReleaseContext”);
}
return(TRUE);
} // end Encryptfile
//获取加密提供者句柄
HCRYPTPROV GetCryptProv()
{
HCRYPTPROV hCryptProv; // 加密服务提供者句柄
//获取加密提供者句柄
if(CryptAcquireContext(
&hCryptProv, // 加密服务提供者句柄
NULL, // 密钥容器名,这里使用登陆用户名
MS_ENHANCED_PROV, // 加密服务提供者
PROV_RSA_FULL, // 加密服务提供者类型,可以提供加密和签名等功能
0)) // 标志
{
printf(“加密服务提供者句柄获取成功!\n”);
}
else
{
//重新建立一个新的密钥集
if(!CryptAcquireContext(&hCryptProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET))
{
HandleError(“重新建立一个新的密钥集出错!”);
}
}
return hCryptProv;
}
// HandleError:错误处理函数,打印错误信息,并退出程序
void HandleError(char *s)
{
printf(“程序执行发生错误!\n”);
printf(“%s\n”,s);
printf(“错误代码为: %x.\n”,GetLastError());
printf(“程序终止执行!\n”);
exit(1);
}
// GenKeyByRandom:通过随机数创建会话密钥
// 参数:hCryptProv CSP句柄
// hDestination 目标文件,导出的会话密钥保存在此文件中
HCRYPTKEY GenKeyByRandom(HCRYPTPROV hCryptProv,FILE* hDestination)
{
HCRYPTKEY hKey;
HCRYPTKEY hXchgKey;
PBYTE pbKeyBlob;
DWORD dwKeyBlobLen;
if(CryptGenKey(
hCryptProv,
ENCRYPT_ALGORITHM,
KEYLENGTH | CRYPT_EXPORTABLE,
&hKey))
{
printf(“一个会话密钥已经被创建. \n”);
}
else
{
HandleError(“Error during CryptGenKey. \n”);
}
//--------------------------------------------------------------
// 创建交换密钥
if(CryptGenKey(
hCryptProv,
AT_KEYEXCHANGE,
0,
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)
最后
前端CSS面试题文档,JavaScript面试题文档,Vue面试题文档,大厂面试题文档,需要的读者可以戳这里免费领取!
几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**
因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-NvNwma81-1713611860536)]
[外链图片转存中…(img-tDVuM5WH-1713611860536)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!
[外链图片转存中…(img-R59xNwOw-1713611860537)]
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)
[外链图片转存中…(img-Jt5ztE3S-1713611860537)]
最后
前端CSS面试题文档,JavaScript面试题文档,Vue面试题文档,大厂面试题文档,需要的读者可以戳这里免费领取!
[外链图片转存中…(img-sDO8y1m9-1713611860538)]
[外链图片转存中…(img-0PIHb0Zi-1713611860538)]