我在这里发布仅供参考——JSL 中的加密类不安全。我建议只使用函数而不是类,因为函数不易受此影响。
问题在于 JMP 类是自省的,而编译的函数不是。考虑下面的类,它包含一个我非常想保密的方法:
Define Class(
"complex",
real = 0;
imag = 0;
_init_ = Method( {a, b},
real = a;
imag = b;
);
secret method = Method( {secret input 1, secret input 2 = "foo"},
{Default Local},
my secret password = "password123";
my secret connection database = "database=UML_4x7z;source=axml1131;pwd=my_great_password";
Eval( Eval Expr(
my ultra secret program = Run Program(
Executable( "secret_exe.exe" ),
Options( Expr( "-o " || my secret connection database ) )
)
) );
);
Add = Method( {y},
New Object( complex( real + y:real, imag + y:imag ) )
);
Sub = Method( {y},
New Object( complex( real - y:real, imag - y:imag ) )
);
Mul = Method( {y},
New Object( complex( real * y:real - imag * y:imag, imag * y:real + real * y:imag ) )
);
Div = Method( {y},
t = New Object( complex( 0, 0 ) );
mag2 = y:Magsq();
t:real = real * y:real + imag * y:imag;
t:imag = imag * y:real + real * y:imag;
t:real = t:real / mag2;
t:imag = t:imag / mag2;
t;
);
Magsq = Method( {},
real * real + imag * imag
);
Mag = Method( {},
Sqrt( real * real + imag * imag )
);
_to string_ = Method( {},
Char( real ) || " + " || Char( imag ) || "i"
);
_show_ = _to string_;
);如果您使用此脚本并对其进行加密(使用 Edit->Encrypt Script...),那么理想情况下,内部代码不应该对您可能分发给的任何最终用户很容易看到。然而,事实并非如此。解构和重建实际上非常容易。
这里有几个函数可以解构加密的方法(这是问题所在),然后为了方便起见对其进行重构:
clref = New Object( complex( 1, 2 ) );
introspect = Function( {obj},
{Default Local},
i = 1;
obj part = Arg( obj, 1 );
ret = Eval List( {Head Name( obj part )} );
While( !Is Empty( Arg( obj part, i ) ),
moil = Eval List({Arg( obj part, i)} );
ret[N Items( ret ) + 1] = If( N Arg( Arg( moil, 1 ) ) > 0, Recurse( moil ), Head Name( Arg( moil, 1 ) ) );
i++
);
ret
);
Clear Log();
deconstructed = introspect( Eval List( {Name Expr( clref:secret method )} ) );
Show( deconstructed );
reconstruct = Function( {input},
{Default Local},
init = Parse( input[1] || "()" );
If( Is List( input ) & N Items( input ) > 1,
For( i = 2, i <= N Items( input ), i++,
If( Is List( input[i] ),
Insert Into( init, Try( ( s = Recurse( input[i] ); s )[1], Char( s ) ) )
,
Insert Into( init, Parse( input[i] ) )
)
);
);
Eval List( {Name Expr( init ) } );
);
Show( reconstruct( v ) );请注意,这里有两个警告——它不能轻易区分字符串和名称(但作为人类的你可能可以),并且它不会看到这样一个构造的中心参数类:方法(arg1,arg2):returned_class_method(arg); ,其中第一个方法返回一个您进一步调用其方法的类。即使有这些限制,也可以非常快速地找到密码/敏感信息的实施细节。
同样,我的建议是,如果您出于安全目的加密一个脚本/多个脚本,那么不要依赖类。