当前位置: 首页 > 学习 > 电脑学习 > 程序设计 > JAVA > J2ME > 正文

保护您的 J2ME/MIDP 应用程序(3)

http://www.zk168.com.cn  招考学习网 2006-4-11 3:21:52
-----------------------------------------------------------[交流]-[打印]-[发送]-[收藏]--
保护您的 J2ME/MIDP 应用程序(3)

椭圆曲线 DSA 签名示例
在 ECDSASigUtil 类中,首先定义您计划使用的椭圆曲线模型,如清单 7 所示:

清单 7. 定义椭圆曲线模型
private static BigInteger q = new
BigInteger("6277101735386680763835789423207666416083908700390324961279");
private static BigInteger a = new
BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16);
private static BigInteger b = new
BigInteger("64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1", 16);

private static BigInteger n = new
BigInteger("6277101735386680763835789423176059013767194773182842284081");
private static byte [] G =
Hex.decode("03188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012");

ECDSASigUtil.generateKeys() 方法使用清单 7 中的模型生成随机的密钥对。正如前面提到的那样,这个步骤通常由中央认证中心在脱机状态下完成。

清单 8. 使用清单 7 中的模型生成随机的密钥对
// Get a secure random source.
SecureRandom sr = new SecureRandom();

ECCurve.Fp curve = new ECCurve.Fp(q, a, b);
ECDomainParameters ECDomPara = new ECDomainParameters(curve,
curve.decodePoint(G),
n );
ECKeyGenerationParameters ECKeyGenPara =
new ECKeyGenerationParameters(ECDomPara, sr);
ECKeyPairGenerator ECKeyPairGen = new ECKeyPairGenerator();
ECKeyPairGen.init( ECKeyGenPara );
AsymmetricCipherKeyPair keyPair = ECKeyPairGen.generateKeyPair();

privKey = (ECPrivateKeyParameters) keyPair.getPrivate();
pubKey = (ECPublicKeyParameters) keyPair.getPublic();

公钥以参数 Q 来描述,并且用 pubKey.getQ() 方法来检索它。为了避免与模型参数 q 产生混淆,在方法中使用 QQ ,XML 元素名使用大写的 Q 。清单 9 显示了 ECDSAUtil 类中的方法。这些方法检索模型和密钥参数,它们是重新构造公钥对象所必需的。

清单 9. 用于检索模型和密钥参数的 ECDSAUtil 方法
// public key specific field
public static String getQQ() throws Exception {
return (new String(Base64.encode(pubKey.getQ().getEncoded())));
}
// Key parameter fields. Could also be retrieved from pubKey.
public static String getQ() throws Exception {
return (new String(Base64.encode(q.toByteArray())));
}
public static String getA() throws Exception {
return (new String(Base64.encode(a.toByteArray())));
}
public static String getB() throws Exception {
return (new String(Base64.encode(b.toByteArray())));
}
public static String getN() throws Exception {
return (new String(Base64.encode(n.toByteArray())));
}
public static String getG() throws Exception {
return (new String(Base64.encode(G)));
}

通过使用生成的私钥,实用程序类 ECDSASigUtil 可以从摘要获取两部分 DSA 签名 R 和 S :

清单 10. 检索 DSA 签名
static public String [] getSignature (String digest) throws Exception {
// Sign
ECDSASigner signer = new ECDSASigner();
signer.init( true, privKey );
BigInteger [] sigArray = signer.generateSignature( digest.getBytes());

String [] result = new String [2];
// Signature R
result[0] = new String(Base64.encode(sigArray[0].toByteArray()));
// Signature S
result[1] = new String(Base64.encode(sigArray[1].toByteArray()));

return result;
}

服务器将摘要、签名和密钥参数编码成 ASCII 文本格式并以 XML 数字签名格式嵌入该文本。和检索方法名中一样,公钥参数 Q 被记录为 QQ ,以将它与相应 XML 元素中的密钥参数 q 区分开来,如清单 11 所示:

清单 11. 编码并以数字签名格式嵌入
<SignedMesg>
<mesg>Hello World</mesg>
<Signature>
<SignedInfo>
<SignatureMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#dsa-sha1" />
<DigestValue>Ck1VqNd45QIvq3AZd8XYQLvEhtA=</DigestValue>
</SignedInfo>
<SignatureValue>
<R>NK/EIL2lrbFFCThnEuYlUWzh6IEfMsts</R>
<S>AMeJDecKWrQO6Eeehl3het+FlDDL4IedCA==</S>
</SignatureValue>
<KeyInfo>
<KeyValue>
<ECKeyValue>
<QQ>AwCiF5uG+DII/x1XTq84fLm4eGN2fED1PYc=</QQ>
<Q>AP////////////////////7//////////w==</Q>
<A>AP////////////////////7//////////A==</A>
<B>ZCEFGeWcgOcPp+mrciQwSf643uzBRrmx</B>
<N>AP///////////////5ne+DYUa8mxtNIoMQ==</N>
<G>AxiNqA6wMJD2fL8g60OhiAD0/wr9gv8QEg==</G>
</ECKeyValue>
</KeyValue>
</KeyInfo>
</Signature>
</SignedMesg>

验证 MIDP 应用程序从 XML 文档解析出摘要、密钥参数和签名,重新构造公钥并使用清单 12 中显示的方法来验证签名:

清单 12. 验证签名
static public boolean verify (String digest,
String sig_r, String sig_s,
String key_q, String key_a,
String key_b, String key_n,
String key_G, String key_Q ) {

BigInteger q = new BigInteger( Base64.decode(key_q) );
BigInteger a = new BigInteger( Base64.decode(key_a) );
BigInteger b = new BigInteger( Base64.decode(key_b) );
BigInteger n = new BigInteger( Base64.decode(key_n) );

byte [] G = Base64.decode(key_G);
byte [] Q = Base64.decode(key_Q);

BigInteger r = new BigInteger( Base64.decode(sig_r) );
BigInteger s = new BigInteger( Base64.decode(sig_s) );

ECCurve.Fp curve = new ECCurve.Fp(q, a, b);
ECDomainParameters ECDomPara = new ECDomainParameters(
curve, curve.decodePoint(G), n );
ECPublicKeyParameters pubKey = new ECPublicKeyParameters(
curve.decodePoint(Q), ECDomPara );

// Verify
ECDSASigner signer = new ECDSASigner();
signer.init( false, pubKey );
boolean result = signer.verifySignature( digest.getBytes(), r, s );
return result;
}

RSA 签名示例
RSA 算法只有一个模型参数 Exponent :

private static BigInteger pubExp = new BigInteger("11", 16);

RSASigUtil.generateKeys() 方法使用 Exponent 生成随机的密钥对。同样,这个步骤通常由中央认证中心在脱机状态下完成。

清单 13. 生成随机的密钥对
SecureRandom sr = new SecureRandom();
RSAKeyGenerationParameters RSAKeyGenPara =
new RSAKeyGenerationParameters(pubExp, sr, 1024, 80);
RSAKeyPairGenerator RSAKeyPairGen = new RSAKeyPairGenerator();
RSAKeyPairGen.init(RSAKeyGenPara);
AsymmetricCipherKeyPair keyPair = RSAKeyPairGen.generateKeyPair();

privKey = (RSAPrivateCrtKeyParameters) keyPair.getPrivate();
pubKey = (RSAKeyParameters) keyPair.getPublic();

(未完待续)

-----------------------------------------------------------[交流]-[打印]-[发送]-[收藏]--
最新入库:
 
·实质、过程及意义——阿多尔诺“否定的辩证法”探微
·从Ontology的译名之争看哲学术语的翻译原则
·论马克思主义哲学经典的解释——解释学方法及其在马克
·中国哲学当前的核心与周边问题
·和合学与21世纪文化价值和科技
·中国文化的和合精神与21世纪
·宗教之间理当相互宽容
·上半个世纪的自由主义
·殷周至春秋时期神人关系之演进
·大学之道:构建以“三纲八目”为核心的道德修养体系
相关内容:
 
网友点评:
 
会员名称:
密码:匿名 ·注册·忘记密码?
评论内容:
(最多300个字符)
  查看评论
友情提醒:
 1.库中的资料大都来自互联网、网友上传、各类书籍,在录入的过程中难免会出现错误,恳请网
 友来信指正!
 2.如果网友在本库中未能找到所需要的材料,请登陆到我们的论坛《招考学习网》版块!
 3.考友想加入招考学习网的编辑部,请发信到XueXiWang#Gmail.com(#改为@)附带个人简历
 4.如需转载请注明出处及作者,谢谢合作!
 5.如果您有更好的建议或意见请EMAIL:XueXiWang#Gmail.com (#改为@)
 6.凡标题中有注有“[NO]”字样均不含答案且答案整理中.
 7.如本库中转载文章涉及版权等问题,请相关网站或作者在两周内发邮件通知(EMAIL:  XueXiWang#Gmail.com (#改为@))我们,我们接到通知后立即删除该文章及链接!
你问我答 更多>>