我有一个 Flex 4 应用程序,它使用 2048 位私有 RSA 密钥来加密/签署一些大约 30 个字符长的字符串值。
我目前正在使用 com.hurlant.crypto.RSAKey 实现来执行此操作,但我面临以下限制:
- 花费的时间太长(签署 30 个字符的字符串大约需要 4 秒)
- UI 在类处理时冻结(实现显然不使用事件或块处理)
我一直在寻找其他库,但到目前为止我还没有找到任何其他具有相同功能级别的库(从 PEM 字符串中读取 RSA 密钥,允许 RSA.sign()、RSA.encrypt 和解密),可以免费使用在商业应用中,这比我目前使用的要快。
所以我的问题是:
- 有谁知道一个很棒/快速的 AS3 库可以做到这一点?
- 如果没有,而我决定自己从头开始编写一个,我是否会面临同样的问题,因为闪存平台以某种方式引起了低性能?
EDIT2:下面的代码使用存储在文件中的 PEM 编码私钥。如果您没有,您可以使用以下代码创建一个:
var exp:String = "10001";
var bits:int = 2048;
rsa = RSAKey.generate(bits, exp);
不要忘记坐下来喝杯咖啡,因为它需要将近一分钟才能生成。
编辑:这是一段显示限制的代码。只需单击开始按钮,即可查看进度条和应用程序是如何完全冻结的。
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<fx:Script>
<![CDATA[
import com.hurlant.crypto.rsa.RSAKey;
import com.hurlant.util.der.PEM;
import mx.utils.Base64Encoder;
var pkfilePath:String = "/Users/david/Desktop/private_key.pem";
var stringToSign:String = "Hello this is a string to be signed by an efficient AS3 library";
private function readPKContent():String {
var f:File = new File(pkfilePath);
var fs:FileStream = new FileStream();
fs.open(f,FileMode.READ);
var rawKey:String = fs.readUTFBytes(fs.bytesAvailable);
fs.close();
return rawKey;
}
private function logTime(msg:String, start:Date, end:Date):void {
resultTA.text = msg + " " + (end.time-start.time) + " ms\n" + resultTA.text;
}
protected function button1_clickHandler(event:MouseEvent):void
{
cryptWithHurlant();
}
private function cryptWithHurlant():void {
var start:Date = new Date();
//Load key and use it to sign something
var rawPK:String = readPKContent();
var time:Date = new Date();
var rsa:RSAKey = PEM.readRSAPrivateKey(rawPK);
logTime("Hurlant:ReadRSA", time, new Date());
//Compute a signature of the string
var srcBA:ByteArray = new ByteArray();
srcBA.writeUTFBytes(stringToSign);
//Now sign inside the second BA
var desBA:ByteArray = new ByteArray();
time = new Date();
rsa.sign(srcBA, desBA, srcBA.length);
logTime("Hurlant:Encrypt", time, new Date());
//desBA.position = 0;
//Recover as a Base64 response
//var b64encoder:Base64Encoder = new Base64Encoder();
//time = new Date();
//b64encoder.encodeBytes(desBA);
//logTime("Base64:Encoded "+b64encoder.toString(),time, new Date());
logTime("Hurlant:Total",start,new Date());
}
]]>
</fx:Script>
<s:VGroup width="100%" height="100%" horizontalAlign="center">
<s:Button click="button1_clickHandler(event)" label="Start"/>
<mx:ProgressBar indeterminate="true"/>
<s:TextArea width="100%" height="100%" editable="false" id="resultTA"/>
</s:VGroup>
</s:WindowedApplication>