伪随机加密
pascal吧
全部回复
仅看楼主
level 8
panpy22 楼主
伪随机数的生成(MT19937-64算法)
{$mode objfpc}//要使用class前必须打开的编译开关
unit Rand_MT19937;
interface
type
MT19937=class//为了方便采用面向对象编程
private
const
NN=312;
MM=156;
MATRIX_A=$B5026F5AA96619E9;
UM=$FFFFFFFF80000000;
LM=$7FFFFFFF;
var
mt:array[0..NN-1]of uint64;
mti:uint16;
public
constructor Create(const seed:uint64);
function RandBit:boolean;
function RandU8:uint8;
function Rand8:int8;
function RandU16:uint16;
function Rand16:int16;
function RandU32:uint32;
function Rand32:int32;
function RandU64:uint64;
function Rand64:int64;
function RandInt(const range:int64):int64;
function Random:extended;
function Uniform(const a:extended=1;const b:extended=0):extended;
function Normal(const mu:extended=0;const sigma:extended=1):extended;
end;
implementation
constructor MT19937.Create(const seed:uint64);
var i:uint16;
begin
mt[0]:=seed;
for i:=1 to NN-1 do
mt[i]:=6364
13622384679
3005*(mt[i-1]xor(mt[i-1]shr 62))+i;
mti:=0
end;
function MT19937.RandBit:boolean;//[false,true]
begin
Result:=boolean(RandU64)
end;
function MT19937.RandU8:uint8;//[0,2^8-1]
begin
Result:=uint8(RandU64)
end;
function MT19937.Rand8:int8;//[-2^7,2^7-1]
begin
Result:=int8(RandU64)
end;
function MT19937.RandU16:uint16;//[0,2^16-1]
begin
Result:=uint16(RandU64)
end;
function MT19937.Rand16:int16;//[-2^15,2^15-1]
begin
Result:=int16(RandU64)
end;
function MT19937.RandU32:uint32;//[0,2^32-1]
begin
Result:=uint32(RandU64)
end;
function MT19937.Rand32:int32;//[-2^31,2^31-1]
begin
Result:=int32(RandU64)
end;
function MT19937.RandU64:uint64;//[0,2^32-1]
var
i:uint16;
mag01:array[0..1]of uint64=(0, MATRIX_A);
begin
if mti>=NN then
begin
for i:=0 to NN-MM-1 do
begin
Result:=(mt[i]and UM)or(mt[i+1]and LM);
mt[i]:=mt[i+MM]xor(Result shr 1)xor mag01[Result and 1]
end;
for i:=NN-MM to NN-2 do
begin
Result:=(mt[i]and UM)or(mt[i+1]and LM);
mt[i]:=mt[i+(MM-NN)]xor(Result shr 1)xor mag01[Result and 1]
end;
Result:=(mt[NN-1]and UM)or(mt[0]and LM);
mt[NN-1]:=mt[MM-1]xor(Result shr 1)xor mag01[Result and 1];
mti:=0
end;
Result:=mt[mti];
Result:=Result xor((Result shr 29)and $5555555555555555);
Result:=Result xor((Result shl 17)and $71D67FFFEDA60000);
Result:=Result xor((Result shl 37)and $FFF7EEE000000000);
Result:=Result xor(Result shr 43);
inc(mti)
end;
function MT19937.Rand64:int64;//[0,2^64-1]
begin
Result:=int64(RandU64)
end;
function MT19937.RandInt(const range:int64):int64;//[0,range]
begin
Result:=round(Random*range)
end;
function MT19937.Random:extended;//[0,1]
begin
Result:=Extended(RandU32)/$ffffffffffffffff
end;
function MT19937.Uniform(const a:extended=1;const b:extended=0):extended;//[a,b]
begin
Result:=Random*(a-b)+b
end;
function MT19937.Normal(const mu:extended=0;const sigma:extended=1):extended;
begin
Result:=sqrt(-2*ln(Uniform))*cos(2*pi*Random)*sigma+mu//Box-Muller
end;
end.
加密
{$mode objfpc}
unit Encrypt_MT19937;
interface
uses Rand_MT19937;
type
Encrypt=class//加密解密算法相同
private
FRandom:MT19937;
public
constructor Create(const Key:uint64);
destructor Destroy;override;
function EncryptBit(const data:boolean):boolean;
function EncryptU8(const data:uint8):uint8;
function EncryptU16(const data:uint16):uint16;
function EncryptU32(const data:uint32):uint32;
function EncryptU64(const data:uint64):uint64;
end;
implementation
constructor Encrypt.Create(const Key:uint64);
begin
FRandom:=MT19937.Create(Key)
end;
destructor Encrypt.Destroy;
begin
FRandom.Destroy
end;
function Encrypt.EncryptBit(const data:boolean):boolean;
begin
Result:=data xor FRandom.RandBit
end;
function Encrypt.EncryptU8(const data:uint8):uint8;
begin
Result:=data xor FRandom.RandU8
end;
function Encrypt.EncryptU16(const data:uint16):uint16;
begin
Result:=data xor FRandom.RandU16
end;
function Encrypt.EncryptU32(const data:uint32):uint32;
begin
Result:=data xor FRandom.RandU32
end;
function Encrypt.EncryptU64(const data:uint64):uint64;
begin
Result:=data xor FRandom.RandU64
end;
end.
{
加密解密算法相同
操作1次加密
连续操作2次解密
明文与MT19937伪随机数做xor运算得密文
密文与MT19937伪随机数做xor运算得明文
只有伪随机种子相同时才能还原
伪随机种子即为密钥
理论上伪随机算法随机性越强保密性越高
}
2017年04月12日 13点04分 1
level 8
panpy22 楼主
示例程序:
program Encrypt_Test;
{
加密解密算法相同
操作1次加密
连续操作2次解密
}
uses Encrypt_MT19937 in 'storage/emulated/0/Encrypt_MT19937.pp';
var
Encryptor:Encrypt;
PassWord:uint64;
FileAddr:string;
fin,fout:file of uint8;
temp:uint8;
begin
write('Password: ');
readln(PassWord);
Encryptor:=Encrypt.Create(Password);
write('Input File: ');
readln(FileAddr);
assign(fin,FileAddr);
reset(fin);
write('Output File: ');
readln(FileAddr);
assign(fout,FileAddr);
rewrite(fout);
while not eof(fin)do
begin
read(fin,temp);
write(fout,Encryptor.Encrypt(temp))
end;
close(fin);
close(fout);
Encryptor.Destroy;
writeln('Success')
end.
2017年04月12日 13点04分 2
修正:write那句改为write(fout,Encryptor.EncryptU8(temp))
2017年04月13日 03点04分
level 8
panpy22 楼主
@徐一凡_exe 这个伪随机加密算法应该比你的转轮加密算法安全性高
2017年04月12日 13点04分 3
level 8
panpy22 楼主
该方法优点是较难破解,缺点是生成伪随机数的时间开销较大,不过MT19937应该已经是安全的伪随机算法中最快的一个了。
2017年04月12日 14点04分 6
level 9
MT19937其实不比同余难破,而且其实不稳定。。
2017年04月13日 07点04分 7
好吧,是不是在已知明文的情况下能够破解密钥
2017年04月13日 09点04分
level 14
如果不考虑border|length的字符串(诸如ababab,他会和ab等价之类)的话,
我感觉把密码和原文循环卷积一下就可以了。。(就是循环着异或一下、),再做一次=解密。
这个代码不能判断密码是否正确吧。
2017年04月13日 09点04分 8
level 8
panpy22 楼主
再次升级
已知明文密文推断伪随机序列的难度更大
{$mode objfpc}
unit EncryptU8_MT19937;
interface
uses Random_MT19937;
type
Encrypt8=class
private
FRandom:MT19937;
FMap:array[uint8,uint8]of uint8;
public
constructor Create(const Key:uint64);
destructor Destroy;override;
function Encrypt(const data:uint8):uint8;
end;
implementation
constructor Encrypt8.Create(const Key:uint64);
var
i,j,t1,t2,temp:uint8;
s:set of uint8;
begin
FRandom:=MT19937.Create(Key);
for i in uint8 do
begin
for j in uint8 do
FMap[i,j]:=j;
s:=[];
for j:=0 to 63 do
begin
repeat
t1:=FRandom.RandU8;
t2:=FRandom.RandU8
until (t1<>t2)and not((t1 in s)or(t2 in s));
include(s,t1);
include(s,t2);
temp:=FMap[i,t1];
FMap[i,t1]:=FMap[i,t2];
FMap[i,t2]:=temp
end
end
end;
destructor Encrypt8.Destroy;
begin
FRandom.Destroy
end;
function Encrypt8.Encrypt(const data:uint8):uint8;
var n:uint8;
begin
case FRandom.RandU8 and 7 of//增加变化
0:n:=FRandom.RandU8;
1:n:=not FRandom.RandU8;
2:n:=swap(FRandom.RandU8);
3:n:=not swap(FRandom.RandU8);
4:n:=FRandom.RandU8 xor FRandom.RandU8;
5:n:=not(FRandom.RandU8 xor FRandom.RandU8);
6:n:=swap(FRandom.RandU8 xor FRandom.RandU8);
7:n:=not swap(FRandom.RandU8 xor FRandom.RandU8);
8:n:=FRandom.RandU8 and FRandom.RandU8;
9:n:=not(FRandom.RandU8 and FRandom.RandU8);
10:n:=swap(FRandom.RandU8 and FRandom.RandU8);
11:n:=not swap(FRandom.RandU8 and FRandom.RandU8);
12:n:=FRandom.RandU8 or FRandom.RandU8;
13:n:=not(FRandom.RandU8 or FRandom.RandU8);
14:n:=swap(FRandom.RandU8 or FRandom.RandU8);
15:n:=not swap(FRandom.RandU8 or FRandom.RandU8)
end;
Result:=FMap[FRandom.RandU8 xor n,data xor n]xor n
end.
2017年04月14日 13点04分 11
加密解密算法依然相同
2017年04月14日 13点04分
确实是难以破解,因为你都不知道一个密码是不是对的[滑稽]
2017年04月16日 06点04分
连暴力破解也没有用,这个代码可以的[滑稽]
2017年04月16日 07点04分
level 14
抛一个用密码明文异或的程序、不过明明是Pascal吧搞什么加密[汗]
uses SysUtils;
function GetFSize(const s:ansistring):int64;
var f:file;
begin
assign(f,s); reset(f,1); GetFSize:=FileSize(f); close(f)
end;
type
un=record case integer of 0:(longint:longint); 1:(str:array[0..3]of char) end;
const
E=257;
P=6662333;
ErEncode:array[0..1]of string=('Success.',
'File not found.');
EriEncode:array[0..3]of string=('Success.',
'File not found.',
'File not a [shy-encode] file.',
'Password wrong.');
var
stdin,stdout:text;
function Encode:longint;
var
Src,Cre,Pas:ansistring;
Salt:string='';
c:char;
N,Hash:int64;
i,j:longint;
tmp:un;
begin
randomize;
write('Key in source file:'); readln(Src);
if not FileExists(Src) then exit(1);
Cre:=Src+'.shy';
write('Key in password:'); readln(Pas);
for i:=1 to 5 do Salt:=Salt+char(random(256));
Pas:=Pas+Salt;
Hash:=0;
for i:=1 to length(Pas) do Hash:=(Hash*E+ord(Pas[i]))mod P;
N:=GetFSize(Src);
assign(stdin,Src); reset(stdin);
assign(stdout,Cre); rewrite(stdout);
write(stdout,'SHY*');
tmp.longint:=length(Src);
write(stdout,tmp.str[0],tmp.str[1],tmp.str[2],tmp.str[3]); write(stdout,Src);
write(stdout,Salt);
j:=1;
for i:=1 to n do
begin
read(stdin,c);
Hash:=(Hash*E+ord(c))mod P;
c:=char(ord(c)xor ord(Pas[j]));
write(stdout,c);
inc(j); if j=length(Pas) then j:=1
end;
tmp.longint:=Hash;
write(stdout,tmp.str[0],tmp.str[1],tmp.str[2],tmp.str[3]);
close(stdin); close(stdout);
exit(0)
end;
function iEncode:longint;
var
Src,Cre,Pas:ansistring;
c:char;
Salt:string='';
N,i,j:longint;
Hash:int64;
tmp:un;
begin
write('Key in source file:'); readln(Src);
if not FileExists(Src) then exit(1);
N:=GetFSize(Src);
write('Key in password:'); readln(Pas);
assign(stdin,Src); reset(stdin);
read(stdin,tmp.str[0],tmp.str[1],tmp.str[2],tmp.str[3]);
if tmp.str<>'SHY*' then exit(2);
read(stdin,tmp.str[0],tmp.str[1],tmp.str[2],tmp.str[3]);
Cre:='';
for i:=1 to tmp.longint do
begin read(stdin,c); Cre:=Cre+c end;
for i:=1 to 5 do
begin read(stdin,c); Salt:=Salt+c end;
Pas:=Pas+Salt;
Hash:=0;
for i:=1 to length(Pas) do Hash:=(Hash*E+ord(Pas[i]))mod P;
assign(stdout,Cre); rewrite(stdout);
dec(N,17+tmp.longint);
j:=1;
for i:=1 to n do
begin
read(stdin,c);
c:=char(ord(c)xor ord(Pas[j]));
Hash:=(Hash*E+ord(c))mod P;
write(stdout,c);
inc(j);
if j=length(Pas) then j:=1
end;
read(stdin,tmp.str[0],tmp.str[1],tmp.str[2],tmp.str[3]);
close(stdin); close(stdout);
if tmp.longint<>Hash then exit(3);
exit(0)
end;
begin
writeln(ErEncode[Encode]);
writeln(EriEncode[iEncode])
end.
2017年04月15日 05点04分 12
加密这玩意只要过程足够复杂就基本上就
2017年04月16日 04点04分
十分安全了,但是一个加密算法再复杂也会被破解。这是一个普遍的规律。
2017年04月16日 04点04分
@徐一凡_exe 哦、破解过程要花1000万年以上那确实也算可以破解。。
2017年04月16日 05点04分
@徐一凡_exe 而且我这个仅仅无聊写了写加密、、只是把密码和原文异或了一下、、然后Hash检验解密的文件是否和原文件相同。
2017年04月16日 05点04分
level 8
panpy22 楼主
{$mode objfpc}
var
state:array[0..1]of uint64;
EnMap,DeMap:array[uint8,uint8]of uint8;
Last:uint8;
U64:uint64=0;
index:uint8=7;
procedure Init_Rand(const seed0,seed1:uint64);
begin
state[0]:=seed0;
state[1]:=seed1
end;
function XorShift128Plus_RandU64:uint64;
function rotl(const x:uint64;const k:int16):uint64;inline;
begin
Result:=(x shl k)or(x shr(64-k))
end;
var
s1:uint64;
begin
s1:=state[1];
result:=state[0]+s1;
s1:=s1 xor state[0];
state[0]:=rotl(state[0],55)xor s1 xor(s1 shl 14);
state[1]:=rotl(s1,36)
end;
function RandU8:uint8;
begin
if index=7 then
begin
index:=0;
U64:=XorShift128Plus_RandU64
end
else inc(index);
Result:=U64 and $ff;
U64:=U64 shr 8;
end;
procedure Init_EncryptU8;
var
i,j,t:uint8;
s:set of uint8;
begin
Last:=RandU8;
for i:=255 downto 0 do
begin
s:=[];
for j:=255 downto 0 do
begin
repeat
t:=RandU8
until not(t in s);
include(s,t);
EnMap[i,j]:=t
end
end
end;
function EncryptU8(const data:uint8):uint8;
var
i,a,b,c:uint8;
begin
c:=RandU8;
a:=c and 7;
b:=(c shr 3)and 7;
c:=c shr 6;
Result:=EnMap[RandU8 xor Last,uint8((uint16(data)shl(8-a))or(data shr a)){移位}xor Last]xor Last;//映射
for i:=c downto 0 do
Result:=EnMap[Last,uint8((uint16(Result)shl(8-b))or(Result shr b)){移位}xor Last]xor Last;//映射
Result:=uint8((uint16(Result)shl(8-a))or(Result shr a));//移位
Last:=data
end;
2017年04月21日 11点04分 17
level 8
panpy22 楼主
procedure Init_DecryptU8;
var
i,j,t:uint8;
s:set of uint8;
begin
Last:=RandU8;
for i:=255 downto 0 do
begin
s:=[];
for j:=255 downto 0 do
begin
repeat
t:=RandU8
until not(t in s);
include(s,t);
DeMap[i,t]:=j
end
end
end;
function DecryptU8(const data:uint8):uint8;
var
i,a,b,c:uint8;
begin
c:=RandU8;
a:=c and 7;
b:=(c shr 3)and 7;
c:=c shr 6;
Result:=uint8(data shr(8-a))or(uint16(data)shl a);//移位
for i:=c downto 0 do
begin
Result:=DeMap[Last,Result xor Last]xor Last;
Result:=uint8(Result shr(8-b))or(uint16(Result)shl b)
end;
Result:=DeMap[RandU8 xor Last,Result xor Last]xor Last;
Result:=uint8(Result shr(8-a))or(uint16(Result)shl a);
Last:=Result
end;
var
c:char;
n0,n1:uint8;
s:string;
fin,fout:file of uint8;
begin
writeln('Mode:');
writeln('E : Encrypt');
writeln('D : Decrypt');
readln(c);
write('Input File: ');
readln(s);
assign(fin,s);
reset(fin);
write('Output File: ');
readln(s);
assign(fout,s);
rewrite(fout);
write('Password 1: ');//一共2个uint64密码
read(n0);
write('Password 2: ');
read(n1);
Init_Rand(n0,n1);
writeln('Please wait......');
case c of
'E':begin
Init_EncryptU8;
while not eof(fin)do
begin
read(fin,n0);
write(fout,EncryptU8(n0))
end;
end;
'D':begin
Init_DecryptU8;
while not eof(fin)do
begin
read(fin,n0);
write(fout,DecryptU8(n0))
end
end
else halt
end;
writeln('Success')
end.
2017年04月21日 11点04分 18
算法比较复杂。我测试过了,可以正确解密。为了防止暴力破解,Hash code未添加,防止借此检测出密码正确性(反正密码对了可以正确解密,错了就是一堆乱码)。
2017年04月21日 11点04分
伪随机数算法改用更安全快速的 XorShift128+ 算法
2017年04月21日 11点04分
@panpy22 有软用[喷]如果我的算法和你一样没有加验证的话,也是不会被shy大神破解的[喷]
2017年06月16日 04点06分
@徐一凡_exe 如果我把我的算法也设计成不能判断正误的话,同样是不可破解的算法,这样算起来我的算法还比你的效率高呢!
2017年06月16日 04点06分
level 8
楼主,水贴也不是这么容易的
2017年06月16日 04点06分 19
[滑稽]
2017年06月16日 05点06分
level 8
panpy22 楼主
{$goto+}
program Encrypt;
uses Boost in 'storage/emulated/0/Boost.pp',Sysutils;
label 0,1,2,3,4,5,6,7;
var
c:char;
s:string;
fin,fout:file of uint8;
times,i,temp:uint8;
j:uint32;
k:uint64;
t0:extended;
Password,Password2:array[1..128]of uint8;//2
Secrecy:array[1..128]of uint32;//8
Ec:array[1..128]of TEncrypt_XoroShiroPlusU8;
Dc:array[1..128]of TDecrypt_XoroShiroPlusU8 absolute Ec;
begin
writeln('****************************************************************************************************');
writeln;
writeln(' 文件加密器');
writeln;
writeln(' 版权');
writeln;
writeln(' 潘鹏远');
writeln;
writeln(' 保留所有权利');
writeln;
writeln(' 2017 / 3 / 3');
writeln;
writeln(' 汇报漏洞至 [email protected]');
writeln;
writeln('****************************************************************************************************');
writeln;
writeln('警告 :');
writeln;
writeln('在加密前,必须认真牢记 次数 、密码 和 保密等级');
writeln('如果忘记其中任何一个的话,将无法解密文件');
writeln;
writeln('因本程序导致的损失本人概不负责');
writeln;
writeln('****************************************************************************************************');
writeln;
writeln('说明 :');
writeln;
writeln;
writeln('加密次数 [1~128]');
writeln('加密/解密 文件的次数');
writeln('加密次数越多,保密性越高,加密/解密 速度越慢');
writeln('不要输入过大的数字,消耗时间与 加密次数 成正比');
writeln;
writeln;
writeln('密码 [1~255]');
writeln('只接受数字,不接受字母/字符');
writeln('密码不能为0');
writeln;
writeln;
writeln('保密等级 [0~4294967295]');
writeln;
writeln('数字越小,保密等级越高,加密/解密 速度越慢');
writeln('不要输入过小的数字,消耗时间 与 本数字 成反比');
writeln;
writeln('建议的保密等级');
writeln;
writeln('>=1000 速度极快 其实也很难破解');
writeln('<1000 速度较快');
writeln('<100 速度较慢 几乎无法破解');
writeln('<10 速度极慢 机密文件适用');
writeln('=0 速度超级慢 顶级绝密适用 没有密钥的话,绝对破解不了');
writeln;
writeln('****************************************************************************************************');
writeln;
0:writeln('模式:');
2018年09月27日 03点09分 20
level 8
panpy22 楼主
writeln('E:加密');
writeln('D:解密');
readln(c);
writeln;
case c of
'E','e':
begin
1:write('输入文件 : ');
readln(s);
if not FileExists(s)then
begin
writeln('文件名有误');
goto 1
end;
writeln;
assign(fin,s);
reset(fin);
2:writeln('使用 输入向导 或 直接输入代码?');
writeln('输入向导:0');
writeln('输入代码:1');
readln(j);
if j>=2 then
begin
writeln('输入错误');
goto 2
end;
writeln;
if j=0 then
begin
3:write('加密次数 :');
readln(times);
if times=0 then
begin
writeln('输入错误');
goto 3
end;
for i:=1 to times do
begin
writeln;
writeln('第 ',i,' 轮的设置');
write('密码 1:');
readln(Password[i]);
write('密码 2:');
readln(Password2[i]);
write('保密等级:');
readln(Secrecy[i])
end;
writeln;
write('输出代码:');
for i:=1 to times do
begin
write(inttohex(Password[i],2));
write(inttohex(Password2[i],2));
write(inttohex(Secrecy[i],8),' ')
end;
writeln
end
else
begin
write('输入代码:');
readln(s);
for i:=length(s)downto 1 do
if s[i]=' 'then Delete(s,i,1);
if length(s)mod 12<>0 then
begin
writeln;
writeln('代码错误');
halt
end;
times:=length(s)div 12;
for i:=1 to times do
begin
Password[i]:=strtoint('$'+Copy(s,j,2));
Password2[i]:=strtoint('$'+Copy(s,j+2,2));
Secrecy[i]:=strtoint('$'+Copy(s,j+4,8));
inc(j,12)
end
end;
writeln;
writeln('请等待……');
t0:=now;
for i:=1 to times do
Ec[i]:=TEncrypt_XoroShiroPlusU8.Create(Password[i],Password2[i],Secrecy[i]);
k:=filesize(fin);
s:=s+'.encrypt';
assign(fout,s);
rewrite(fout);
while k<>0 do
begin
Dec(k);
read(fin,temp);
2018年09月27日 05点09分 21
level 8
panpy22 楼主
for i:=times downto 1 do
temp:=ShiftRU8(Dc[i].DecryptU8(temp),i)xor i;
if temp<>(Secrecy[j]shr 16)and 255 then
begin
Erase(fout);
writeln('密码 或 保密等级 错误');
halt
end;
read(fin,temp);
for i:=times downto 1 do
temp:=ShiftLU8(Dc[i].DecryptU8(temp),i)xor i;
if temp<>Secrecy[j]shr 24 then
begin
Erase(fout);
writeln('密码 或 保密等级 错误');
halt
end
end;
for i:=1 to times do
Dc[i].Destroy
end;
else
begin
writeln('输入错误');
goto 0
end
end;
close(fin);
close(fout);
writeln;
writeln('耗时:',(now-t0)*86400:0:3,' 秒');
writeln;
writeln('输出文件 : ',s)
end.
2018年09月27日 05点09分 22
level 7

2020年07月22日 08点07分 23
1