AS3中的快速RSA加密

3
我有一个Flex 4应用程序,使用2048位的私钥RSA加密/签名一些大约30个字符长的字符串值。目前我正在使用com.hurlant.crypto.RSAKey实现这一点,但我面临以下限制:
- 它太慢了(签署30个字符的字符串需要大约4秒) - 当类在处理时,UI会冻结(明显的实现没有使用事件或块处理)
我一直在寻找其他库,但到目前为止,我还没有找到任何具有相同功能级别(从PEM字符串读取RSA密钥,允许RSA.sign()、RSA.encrypt和decrypt),可在商业应用中免费使用且比我当前使用的库更快的库。
所以我的问题是:
- 是否有人知道一个很棒/快速的AS3库可以做到这一点? - 如果没有,如果我决定自己从头开始编写一个,我会面临相同的问题,因为低性能与flash平台有关吗?
编辑2:下面的代码使用存储在文件中的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>

@Florent 强的RSA加密是后端服务器的先决条件,因此我必须使用它(就像我在其他非AS3编写的客户端应用程序中已经使用过一样)。 - Davz
编辑库并使其在定时器上分块加密。或者考虑使用线程。 - The_asMan
@The_asMan 是的,我曾考虑使用计时器或事件,因为这样会使应用程序更加响应,但最终可能需要更长时间。无论如何,如果我找不到其他解决方案,那么我想这就是我要做的。关于多线程,在Flash中是不可能的(单线程运行时)。 - Davz
1
@Davz 如果你可以使用Flash Player 11.4 / AIR 3.4,现在可以通过Workers来实现并发。 - NoobsArePeople2
1
@Davz 你可能想要研究一下基于计时器的“线程”实现。这不会加速任何东西,但它将消除UI锁定。我已经在移动设备上使用了这个代码。http://bitsofinfo.wordpress.com/2008/09/22/threads-in-as3-flex-actionscript/ - francis
显示剩余6条评论
1个回答

1

如上所述:

您可能需要研究基于定时器的“线程”实现。这不会加速任何东西,但它将消除UI锁定。我已经在移动设备上使用了这个代码。

根据评论中所说的所有内容和答案的缺失,我认为目前最好的选择是编辑RSA实现,使其能够在f-a提出的伪线程模型下运行。一旦移动平台支持,我将转向工作线程。

参考文献


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接