当我使用由KeyPairGenerator生成的密钥在计算机上运行以下代码时,我大约需要31毫秒。
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.Signature;
public class Crypto {
public static void main(String[] args){
final String PROVIDER_NAME = "SunRsaSign";
final String SIGNATURE_ALGORITHM_NAME = "SHA1withRSA";
try {
byte[] bytesToSign = "TEST".getBytes();
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(4096);
PrivateKey privateKey = kpg.genKeyPair().getPrivate();
Signature rsaSign = Signature.getInstance(SIGNATURE_ALGORITHM_NAME, PROVIDER_NAME);
rsaSign.initSign(privateKey);
rsaSign.update(bytesToSign);
long start = System.currentTimeMillis();
rsaSign.sign();
long end = System.currentTimeMillis();
System.out.println(end-start);
} catch (Exception e) {
System.out.print(e.toString());
}
}
}
但是,当我使用KeySpec运行以下代码时,我得到328毫秒。
import java.security.PrivateKey;
import java.security.Signature;
import java.security.spec.RSAPrivateKeySpec;
import java.math.BigInteger;
import java.security.KeyFactory;
public class Crypto {
public static void main(String[] args){
final String PROVIDER_NAME = "SunRsaSign";
final String SIGNATURE_ALGORITHM_NAME = "SHA1withRSA";
try {
byte[] bytesToSign = "TEST".getBytes();
BigInteger n = new BigInteger("597587226679466141124693638138125299950880068828254488555957644249281492201151725373904252242430008473810144110612094128024063578707460431712823842235991465354560187737393879297229743260146710677226117056578671416566287740136599124897385892941425870120428978181352342388371378999775548901123514895501669300647274487518472636693700503555192766931023284431580962701846364239256545481706926550688122371316117197948006216002474377830241838340355035516984862145128976925834940027104794937790806573064454303239801464883574025970986374457025729491416244044251160491275299917049444537591955178699287053624986215597863163779443074749369005932415039400383140953067480491452272333580572932227865814237470887152932057448674357000903536202101025652676188117995296037813643835836244002726526603485151069928993258393018157442284327764913186610742443124225235294325533610789139086190718423569760575759726606015005217606970790315033865732422275945142140911185854993011517078112760033989491003743777970147736937449399489701150359137542465776194778304313471540815791992057968970251791757741455255986669925249397189780062920148823884414124748384210776408299989145375246596521057664660283677204196251491406330933981965200587649372807527331850099013257897");
BigInteger d = new BigInteger("4595632425140774449957208807568475077822353093511150376614777190009275250154576339906430613701950413824256719589674465424479729674360438494030291537405430497866828426990044023464665617942749014775195126363972265955863237881331857713173970276980616118233916795144751523013552268426795194259216190965909964257232194664224944823437524662279584883855466917214959567904093375903463675828620336322181571862357493748047593464230085088216456147268549642195406724768375183035854704573917278005501724412537726304726489438047535118930941799690876415821196987935099026314948062288370234324829415598279455498832614441633322162210880362668225335174174254925331410135687428608342277292478555925249301141034109001860652817038518162426120218303741256538573731958165872030034502507324328196680907973846309670995934916630480379153721692432821724120534768708296475728203534373370163067285835785480486327238089504618803125757317740030708309519453831883949072027340057586476480382666523830109818313596509315892976057010736043565833515535051861285267156916096112209738518894413968197350931670388334238393788649720192047074674730303813328065901384401315536207657662831106566630368281509079558729496437617044484467087495574832015312198202479584112626996225");
RSAPrivateKeySpec rsaPrivateKeySpec = new RSAPrivateKeySpec(n,d);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(rsaPrivateKeySpec);
Signature rsaSign = Signature.getInstance(SIGNATURE_ALGORITHM_NAME, PROVIDER_NAME);
rsaSign.initSign(privateKey);
rsaSign.update(bytesToSign);
long start = System.currentTimeMillis();
rsaSign.sign();
long end = System.currentTimeMillis();
System.out.println(end-start);
} catch (Exception e) {
System.out.print(e.toString());
}
}
}
我不知道为什么第二个选项这么慢。有任何想法吗?
最佳答案
基准测试本身就是一门科学,尤其是对于像JVM这样复杂的环境。但是,在您的情况下,您的两个示例之间的一个重大区别是,在KeyPairGenerator
情况下,私钥具有其所有可选组件,从而允许中文余数定理(CRT)加速,而在第二种情况下,使用RSAPrivateKeySpec
您仅拥有最小私钥,不允许此类加速。您可以尝试使用 RSAPrivateCrtKeySpec
与之比较的第三种情况。
我可能希望此差异占2-4的系数,而不是10的系数。