一次一密加密程序设计

 先说一下真随机数的概念。一般认为真随机数是一组无任何规律不可重复产生的数字。其实此话有些重复了,可重复产生一定是依照某种规律产生的,所以无任何规律就可以定义了。一般认为只有源于自然的无规律运动才能产生真随机数,如放射性衰变的发生、电子设备的热噪音等的统计可以产生随机数,其实生活中到处是随机现象,只是有些变化缓慢产生的随机数没有实用价值。一般的随机现象,都是规律变化和随机变化的叠加,利用时需要将规律变化部分剔除。随机函数也可以产生看似无规律的数组,也可以是分布均匀的,但却不能产生真随机数,因为所产生的数组是有规律的、周期变化的,是确定的。
密码学意义上的真随机数组,不一定非用自然现象加探测硬件来实现,只要符合无任何规律和不可重复产生就可以了。一种用软件产生密码学意义上的真随机数组的方法是:利用多个性能优良运算方式不同的长周期随机函数,每个都用毫秒级以上精度的时间做随机种子,用它们的运算来产生随机数,并且运算步骤也是随机的变化的,加之运算时间和计算机状态都将影响到计算结果,使得结果是不能复现和毫无规律的。另一种是用“序列数交换法”来实现无任何规律和不可重复产生的随机数组(参见笔者的有关序列数交换法的文章)。
密码和密钥:密钥是用来隐藏信息的数据。一般密钥是指直接和明文作用产生密文的数据。密码一般指用户输入的用于加密解密的数据。一般是程序根据用户密码生成密钥供加密解密使用,所以密码也可以说是原始密钥其衍生物是应用密钥。
现在的加密方法一般可以分为流密码加密或分组密码加密,它们都是有缺陷的,理论上都是可以被破解,道理很简单不管文件多大都用很短的原始密钥加密势必有破绽。但有一种加密方法可以证明是不可破解的,这就是所谓“一次一密”加密方法,这种方法采用真随机数作为密钥,每个密钥只使用一次,并且每个明文单元用一个密钥单元加密,且看下式:
明文 (运算) 密钥 = 密文
因为密钥之间没有任何关系,从上式可见当只知道密文时,一个方程两个未知数,将无法求解。
现在就可以应用了。程序生成或利用外界的真随机数组和被加密文件一一运算产生密钥文件(真随机数组集合)和密文文件。解密时给程序密文文件和密钥文件,运算生成明文文件。
真随机数加密虽然不可破解,但使用起来有不方便的地方。因为一个明文字节需要一个密钥字节,所以密钥文件长度和文件的长度一样,你不可能记忆它,还要保护它的内容不被泄露和损坏。例如需要通过网络传送密件,不但要传送密文,还要传送密钥,需要解决的是如何保存和保护这些数据。
为了能像一般加密软件那样操作简单,程序将密钥文件附在密文的后面或前面。但是必须加密否则等于将秘密公开,加密方式可以有多种选择,例如加密密钥部分、加密密文部分、两者都加密、两者都加密使用相同的密码或使用不同的密码,提供多种方式供用户选择,将有利于提高保密性。但这些方式的加密强度是不同的,以两者都加密使用不同的密码为最高。因为现在密文部分和密钥部分都是乱码,所以对它们加密相对简单,使用长周期的随机函数即可有很好的效果,这里最好也有多种函数并在用时随机选取,如果应用时每次至少两个随机函数参与运算那就更好了,每个随机函数的初值都以不同的方式与用户密码关联,每增加一种可能用到的计算方式将使破解难度增加数倍。加密密码长度设置下限而不设上限,给破解者留下充分的想象空间。如果对加密过的密文或密钥进行破解将很困难,困难在于无法判断解密是否成功,因为解密成功了也是乱码,无奈之下只好盲目穷举,用了哪些随机函数不知道,阶段性解密成功是否不知道,密钥文件的使用起点也不知道(一般不会老实的从头顺序向下应用的),一个可能用到的长周期随机函数就可使穷举攻击面对天文数字的试验,更何况多个!更厉害的做法是随机函数的部分参数随机确定,破解者能从程序知道随机函数的基本计算构架却无法得到随机序列值,因为系数是不确定的。并且面对形形色色的文件种类,判断最终的结果是否正确也是个耽误时间的问题。
加密程序采用多重防穷举设计。首先是输入密码的形式,采用计算机不易识别的图形字符组成校验码让用户输入,只有输入正确才能通过,并可设置私有密码让程序为你专用的同时扼制了穷举法实施,以上这些和文件密码一同输入,具有特色输入方式将使通用的穷举破解软件不能应用。有随机因素存在则使得任何穷举法无法使用。穷举破解是一种利用计算机和程序自身的计算能力和方式,列举所有可能出现的密码,用它们试解密文达到破解目的的方法。对付穷举破解的有效方法是不让其自动运行,只有用户参与才能运行,不给它制造机会。除了输入形式,程序内部还对被解密文件进行检测,如果发现解密者总对某个文件的解密感兴趣就要采取行动了,但要考虑到一般用户密码输入错误的问题。也可以在解密过程中根据某条件暂停执行要求用户根据显示辨别(计算机难以识别的)应答,不应答则无限期等待,应答正确继续运行,不正确退出运行。
经过以上的处理,加密程序虽然使用“一次一密”的加密方法但使用起来和一般加密软件没有多少区别。只是密文的尺寸大了些并且是不能压缩的。因为它的目标是不可破解,所以运算复杂而且运算速度不高,比较适用于需要高保密的文件加密。
无论是外部导入还是自己发生,技术关键是作为密钥一定要用密码学意义的真随机数组。有效扼制穷举攻击。做到以上两点你加密的文件将不可破解,无论破解者拥有多强的计算能力,和使用多长的计算时间,即使是量子计算机也无济于事。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
你的程序加密过OD MD5值支持二次开发使用 防破解验证也可实现一机一码 VC++ 开发 STARTUPINFO startup; PROCESS_INFORMATION process; CString g_strCompanyName1 = ""; CString g_strCompanyName2 = ""; CString g_strCompanyName3 = ""; CString g_strCompanyName = "**"; BOOL CTaiShanApp::InitInstance() { AfxEnableControlContainer(); //#ifdef ZJH m_gMessageID = ::RegisterWindowMessage("WsSendMessageHqData"); CFileFind fnd; if(S_OK != ::CoInitialize (NULL)) return FALSE; // ReadDiskIDPartCwd(); // if(!FyRegister::IsValidUser()) // return FALSE; memset( &startup, 0, sizeof( startup ) ); startup.cb = sizeof( startup ); memset( &process, 0, sizeof( process ) ); if(fnd.FindFile ("WsSendMessageShare.exe")) { m_gbUseExe = true; } hAppMutex=::CreateMutex(NULL,TRUE,m_pszExeName); if(GetLastError() == ERROR_ALREADY_EXISTS) { CWnd *pPrevWnd = CWnd::GetDesktopWindow()->GetWindow(GW_CHILD); while(pPrevWnd) { if(::GetProp(pPrevWnd->GetSafeHwnd(),m_pszExeName)) { if(pPrevWnd->IsIconic()) pPrevWnd->ShowWindow(SW_RESTORE); pPrevWnd->SetForegroundWindow(); pPrevWnd->GetLastActivePopup()->SetForegroundWindow(); return false; } pPrevWnd = pPrevWnd->GetWindow(GW_HWNDNEXT); } return false; } //#endif #ifndef _NET_AUTHEN HMODULE hModule; hModule = LoadLibrary("ide21201.dll"); if (hModule==NULL) { AfxMessageBox("Can't find ide21201.dll"); return FALSE; } char *(WINAPI * GetIdeSerial)(); GetIdeSerial = (char *(WINAPI *)())GetProcAddress(hModule, "GetIdeSerial"); if (GetIdeSerial==NULL) { AfxMessageBox("Can't find GetIdeSerial in ide21201.dll"); return FALSE; } CString strSerialNumber;// = SERIAL_NUMBER; strSerialNumber = GetIdeSerial(); strSerialNumber.TrimLeft(" "); if (strSerialNumber.Compare(SERIAL_NUMBER)!=0) { AfxMessageBox("序列号错误"); return FALSE; } #else CDlgLogin dlgLogin; int nResponse = dlgLogin.DoModal(); if (nResponse!=1) return FALSE; #endif /* CDialogShowInformation dlg; dlg.DoModal();*/ int nResult; m_bAppAuthorized=TRUE; // Standard initialization // If you are not using these features and wish to reduce the size // of your final executable, you should remove from the following // the specific initialization routines you do not need. CTaiTestSplash *m_splash; BOOL SplashOpen=FALSE; m_splash = new CTaiTestSplash; SplashOpen=m_splash->Create(); if( SplashOpen ) m_splash->ShowWindow(SW_SHOW); DWORD Currenttime=GetTickCount(); BeginWaitCursor(); #ifdef TEST_USER1 t = CTime::GetCurrentTime(); CTime t2 = g_timeUseEnd; if(t >= t2) { // AfxMessageBox("试用期已过,若想继续使用,请购买正式版!",MB_OK | MB_ICONSTOP); return false; } else 以上为部分代码
先运行safechat包里的greetigserver.class,之后运行greetingclient.class即可。 如遇报错,请参考:https://blog.csdn.net/fengzun_yi/article/details/104497160 实现过程: 1. 采用TCP通信协议完成接收者发送者双方的消息传递。 2. 利用Diffie-Hellman密钥交换协议生成对称加密通信的通信密钥。 3. 为防止中间人攻击,采用RSA非对称加密算法协助DH算法完成密钥交换。具体过程如下: a. 接收者与发送者双方各自利用RSA算法生成自己的公私钥,并生成数字证书,并在一个CA进行认证。 b. 在DH密钥交换阶段,A生成A的DH协商密钥用于发送给B,该密钥与接收方私钥生成最终通信密钥。发送DH密钥时,A先用自己的私钥加密DH协商密钥,再去CA获得一个真实的B的公钥,用B的公钥对加密过的协商密钥再做一次加密,发送给B。(因为是用B的公钥加密过,只有B有B的私钥,所以接收信息只有B自己可以解密查看,又因为是用A的私钥加密过的,只有A有A的私钥,所以只有用A的公钥可以进行解密,所以可以保证协商密钥确实是A发送过来的,而且发送的信息也无法被中间人解密。)B收到信息之后,先用自己的私钥解密,然后去CA获得A的公钥再对消息解密一次,获得A的DH密钥。B发给A的过程同上。 c. 之后双方执行DH生成本地密钥的过程。A利用B发送过来的密钥和A的DH私钥生成通信密钥。B利用A发送过来的密钥和B的DH私钥生成通信密钥。根据DH原理,两者生成的通信密钥是相同的。 4. 利用上一步生成的通信密钥,采用AES对称加密算法进行加密通信。 为了方便起见,并没用对A和B双方进行颁发证书的操作,A的公钥默认B已经从CA获得,B的公钥默认A已经从CA获得。并且采用java控制台交互,仅仅为演示原理及简单效果。
对于请求 token 的操作,可以使用互斥锁来实现同步操作。在程序中设置一个共享的变量,例如 tokenCount,表示当前可用的 token 数量。在每一次请求 token 的时候,使用互斥锁来确保一次只有一个线程进入临界区,然后检查 tokenCount 是否大于 0,如果大于 0,则将 tokenCount 减 1 并返回一个 token;否则线程必须等待,直到 tokenCount 大于 0,然后再才能获得一个 token。这样就能确保同一时刻只有一个线程可以获得 token,避免了多次请求 token 的情况发生。完整代码如下: ```lua local availableTokens = 100 -- 假设有100个token可用 local lock = require "lock" -- 导入互斥锁库 function requestToken() local token = nil lock.lock() -- 获取互斥锁 if availableTokens > 0 then availableTokens = availableTokens - 1 token = generateToken() -- 生成一个token end lock.unlock() -- 释放互斥锁 return token end ``` 注意:这段代码中的 generateToken() 函数没有实现,具体实现根据需要自行完成。 关于中文加密,也可以使用 Lua 中内置的加密进行处理,例如使用 MD5 摘要算法加密中文字符串: ```lua local md5 = require "md5" -- 导入 md5 库 function encrypt(s) return md5.sumhexa(s) end local s = "你好,世界" local encrypted = encrypt(s) print(encrypted) -- 输出加密后的结果 ``` 需要安装 md5 库,可以通过 LuaRocks 工具进行安装。 以上是关于编程类问题的回答,希望能对您有帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值