保密你的J2ME/MIDP程序(英文)

<script type="text/javascript"><!-- google_ad_client = "pub-2947489232296736"; /* 728x15, 创建于 08-4-23MSDN */ google_ad_slot = "3624277373"; google_ad_width = 728; google_ad_height = 15; //--> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
<script type="text/javascript"><!-- google_ad_client = "pub-2947489232296736"; /* 160x600, 创建于 08-4-23MSDN */ google_ad_slot = "4367022601"; google_ad_width = 160; google_ad_height = 600; //--> </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>

  Securing your ME/' target='_blank' />J2ME/MIDP apps

  Java technology in wireless Web services

  Java-based Web services and wireless Java developMEnt were the two most prominent topics at JavaOne 2002. They represent the future back- and front-end Java technologies in a world of pervasive computing.

  Web services are loosely coupled, interoperable software components based on standard XML communication protocols. The use of Web services enables a vendor to offer services in a specific market where its core competency lies. CustoMErs can then choose to purchase services from multiple vendors, according to their various needs. This convenience MEans that Web services are perfectly suited to serve wireless front ends. The convenience and dynamic nature of wireless information devices allow mobile users to take advantage of modularized and dynamically re-configurable back-end services.

  The Java platform can play several important roles in wireless Web services application developMEnt. On the wireless end, Java 2 Micro Edition (J2ME) offers cross-device compatibility, advanced language features, and extensive libraries to all wireless devices from cell phones to complex hoME wireless information appliances. A key component of J2ME is the Mobile Information Device Profile (MIDP), which defines Java APIs and runtiME environMEnts on cell phones and low-end PDAs. Due to the large number of low-end devices, MIDP is expected to becoME widely deployed in the future.

  From the Web services end, Java 2 Enterprise Edition (J2EE) already has all the necessary APIs and libraries to handle Web services XML MEssages. Core J2EE functions impleMEnted in EJB technology, the JDBC API, and the RMI API can easily be made available to the outside world through Web services interfaces or gateways. To bring these features together and enable wireless Web services applications, the J2ME Web services specification has also been proposed and is currently in the Java Community Process (JSR 172).

  Security in wireless Web services

  Although Java-based wireless Web services have a bright future in the world of pervasive mobile comMErce, the current technology is not yet mature. Security is among the remaining issues yet to be resolved. Wireless communications are easy targets for air wave interception, and wireless devices rarely have the computing power to support strong encryption of all communication data. Moreover, on the back end, Web services run outside corporate firewalls and interact with each other using open MEssaging protocols. Wireless Web services are likewise vulnerable targets for various cracking attacks. Well developed point-to-point security technologies such as SSL/TLS and HTTPS are not suitable for the multiple vendor, multiple interMEdiary Web services network topography -- the focus needs to be on securing the contents themselves rather than the connections over which they travel. Despite the new challenges, Web services themselves, however, can be used to enhance mobile comMErce security. EMErging Web services security specifications enable you to use Web services as security utilities.

  In the paragraphs below, I''''ll discuss a commonly used security technique: digital signature. I will show you how digital signatures are used in XML MEssages to guarantee end-to-end data integrity. I''''ll cover soME examples that illustrate how to impleMEnt XML digital signatures using the popular J2ME/MIDP platform on the wireless end and JavaServer Pages (JSP) technology on the back end. Finally, I will discuss performance issues and the feasibility of using digital signatures on current MIDP devices. MIDP programming details are beyond the scope of this article; if you need a refresher, please see the Resources section.

  Guarantee data integrity using digital signatures

  Let''''s suppose that you are a stock trader and that you use a cell phone to track stock price changes when you are not on the trading floor. In the middle of your commute to work, your phone alerts you that the price of a stock you have been monitoring has dropped below a threshold. Now, should you buy it based on this tip and take advantage of the low price? Before you take any action, you want to be absolutely sure that the tip itself is authentic. If a competitor could intercept and change the MEssage (for example, change the stock symbol), he could lure you into buying the wrong stock and dump his high-priced equity to you. How do you know that your MEssage has not been tampered with en route from your monitoring service to your phone?

  Indeed, data integrity is one of the most important aspects of communication security. Physically secure networks are very expensive and do not cover a wide geographic area. If your business has to rely on the Internet to communicate, you have to face the fact that the Internet offers little security by itself. Internet data packets have to travel through multiple routers and hosts that are controlled by neither party in the conversation before they reach their destinations. Data communications are especially vulnerable over the wireless Internet.

  The tools that coME to our rescue are the Public Key Infrastructure (PKI) and digital signature. (As with MIDP programming, digital signature is beyond the scope of this article; interested readers can refer to the Resources section for more information.) In a nutshell, in a PKI digital signature scheME, each party has two cryptography keys: the public key is available to anyone and the private key is kept secret to oneself. A MEssage encrypted by the private key can only be correctly decrypted by the corresponding public key. When a sender sends out a MEssage, he can accompany the MEssage with a private key encrypted version of the saME MEssage, as well as his public key. The recipient decrypts the encrypted version using the sender''''s public key. If it matches the clear text MEssage, the recipient can know for sure that the MEssage is authentic. The private key encrypted version of the MEssage serves as an integrity verification token and it is called a "digital signature."

  Because the original MEssage might be quite long, and public key algorithms to generate and verify digital signatures are resource intensive, the sender normally calculates a short version of the original MEssage called the "digest" and digitally signs only this version. The digest is a fixed-length, one-way hash of an any-length input MEssage; its calculation is very fast. The recipient first verifies that the MEssage received produces the correct digest. If the digest does not match, the MEssage is rejected before any public key algorithm is perforMEd. That could help prevent a clogging attack, in which the attacker overwhelms a server''''s computational resources by flooding it with fake public key requests.

  In most practical applications, public keys themselves are digitally signed by trusted authorities, becoming "digital certificates" to validate the sender''''s identification. Digital certificate handling is beyond the scope of this article, however, so in the following examples, I will assuME that the senders are trusted and use unsigned public keys to illustrate the approaches.

  XML digital signatures defined

  As I MEntioned earlier, XML is becoming a major data exchange protocol in the world of Web services. XML MEssages that drive Web services often need to go through multiple interMEdiaries before they reach destinations. So, it is important that we secure the communication content from end to end. The best way to do it is to ship an XML docuMEnt and its security information (such as signatures, digests, keys, and so on.) altogether as a single docuMEnt.

  The XML digital signature is a W3C specification to add a digital signature to an XML docuMEnt. The sender can choose to digitally sign the entire docuMEnt or only part of it. Digital signatures, digests, and public keys are formatted into XML eleMEnts. Those extra eleMEnts of security information can envelop the entire original XML MEssage, or alternatively they can be embedded into the original MEssage. In this article, I will use the enveloping format for convenience.

  For the sake of clarity, the XML digital signature examples I use in this article are not completely W3C compliant. For example, I have left out the canonicalization (standardization of XML tags) part because it only ensures the conformity of XML docuMEnts and has nothing to do with security itself. Also, instead of using encoded public keys certificates, I break a key into several paraMEters and pass those paraMEters in separate XML eleMEnts under the public key eleMEnt KeyInfo. That establishes more obvious connections between keys and the Java code that handles them.

  Handling the XML digital signature in MIDP applications

  IBM alphaWorks develops a Java package called XML Security Suite, which supports the latest XML digital signature specification. JSR 105 is a community effort to standardize a set of Java APIs to process XML digital signatures. However, they only work for Java 2 Standard Edition (J2SE), which MEans that you can use XML Security Suite or JSR 105 Java XML digital signature APIs on the server side, but not on the MIDP wireless device side.

  To handle XML digital signatures, the wireless devices being used need to support the following functions:

  Read and write data from/to an XML docuMEnt. In our example MIDP applications, XML docuMEnts and eleMEnts are parsed into Java objects by the kXML parser (see Resources). In addition to kXML, there are several other MIDP XML parsers available under different license terms.

  Sign the MEssage and verify the signature. These functions require a cryptography API that is not part of the current MIDP 1.0 specification.

  In the next section, I will discuss a lightweight Java cryptography package that you can use on both the server side and wireless MIDP device side to generate and verify XML digital signatures.

  The Bouncy Castle Crypto APIs

  Bouncy Castle is an open source, lightweight cryptography package for the Java platform. It supports a large number of cryptography algorithms and provides an impleMEntation for JCE 1.2.1. Because Bouncy Castle is designed to be lightweight, it can run from J2SE 1.4 to J2ME (including MIDP) platforms. It is the only complete cryptography package that runs on MIDP.

  However powerful, there is one major problem with the Bouncy Castle package: the lack of docuMEntation. Online docuMEntation is non-existent and its JavaDoc is not very well written. Similar to many other advanced cryptography packages, the Bouncy Castle package uses type polymorphism extensively to separate general concepts from impleMEnting algorithms. It''''s hard for beginners to decipher the relationships between classes and the correct types for MEthods arguMEnts and return values. Often, the developer has to peek into the source code and test cases to investigate correct ways to do things. Clearly, a guide for the Bouncy Castle package is very much in order.

  In the rest of this article, we will walk through the XML digital signature specification and the usage of several different Bouncy Castle key generators, encoding engines, digital signature singers, and a digest engine.

  Putting it all together

  We''''ve discussed a number of technologies and concepts so far. Below, I''''ve illustrated the complete process: key generation, signing docuMEnts on the server side, encoding and transporting docuMEnts in secure XML format, and verifying docuMEnts on the client side.

  The server generates a pair consisting of a random public key and a private key using a set of key model paraMEters. In real production system, this step is usually not necessary because the key pairs are usually pre-generated and stored in server key stores.

  When a JSP page is accessed, the server calculates a digest for the response MEssage.

  The JSP page then invokes the signer in the "sign" mode and generates a digital signature for the digest using the private key.

  The server embeds the signature information including the digest, digital signature itself, and public key paraMEters in the XML response MEssage.

  The client receives the XML docuMEnt and parses the digest, digital signature, and public key paraMEters into Java application data.

  The client calculates a digest from the clear text MEssage and compares it with the digest from the server. If the two digests do not match, the docuMEnt verification fails; if they do match, go to the next step.

  The client reconstructs the public key using the embedded key paraMEters.

  The client invokes the signer in "verify" mode and passes the digest, the signature, and the public key to verify the signature.

  We''''ll follow these steps to impleMEnt several examples in the next several sections. Because our examples use the saME Bouncy Castle Crypto APIs on both server side and client side, it is very easy to change them to sign a MEssage on the wireless device and verify it on the server side.

  Handling the digest

  As I MEntioned earlier, to improve performance and avoid clogging attacks, you actually sign the MEssage digest rather than the MEssage itself. Listing 1 illustrates how to compute an encoded digest from a piece of text MEssage using the SHA1Digest digest engine.

  Listing 1. Creating an encoded digest

  static public String getDigest( String MEsg ) throws Exception {;

  SHA1Digest digEng = new SHA1Digest();

  byte [] MEsgBytes = MEsg.getBytes();

  digEng.update( MEsgBytes, 0, MEsgBytes.length );

  byte [] digest = new byte[digEng.getDigestSize()];

  digEng.doFinal(digest, 0);

  // Encode the digest into ASCII format for XML

  return (new String(Base64.encode(digest)));

  };

  In the next several sections, we''''ll see how to sign and verify digital signatures using Bouncy Castle''''s DSA, ECC, and RSA signers. Those signers use different algorithms and different keys, and need different paraMEters. We''''ll also discuss how to embed security information (signatures, digests, and public keys) in XML docuMEnts. At the end, I''''ll compare the three signers and suggest future improveMEnts.

  DSA signature example

  The MEthod DSASigUtil.generateKeys() generates key pairs. As I have discussed, this step is normally done offline by a central certificate authority, as shown in Listing 2:

  Listing 2. Generating key pairs

  // Get a secure random source.

  SecureRandom sr = new SecureRandom();

  // Generate DSA paraMEters.

  DSAParaMEtersGenerator DSAParaGen = new DSAParaMEtersGenerator();

  DSAParaGen.init(1024, 80, sr);

  DSAPara = DSAParaGen.generateParaMEters();

  // Get DSA key generation paraMEters.

  DSAKeyGenerationParaMEters DSAKeyGenPara =

  new DSAKeyGenerationParaMEters(sr, DSAPara);

  // Generate keys.

  DSAKeyPairGenerator DSAKeyPairGen = new DSAKeyPairGenerator();

  DSAKeyPairGen.init( DSAKeyGenPara );

  AsymMEtricCipherKeyPair keyPair = DSAKeyPairGen.generateKeyPair();

  privKey = (DSAPrivateKeyParaMEters) keyPair.getPrivate();

  pubKey = (DSAPublicKeyParaMEters) keyPair.getPublic();

  The generated public key is characterized by a paraMEter Y, and it is retrieved by the pubKey.getY() MEthod. ParaMEters G, P, and Q describe the model. The following MEthods in class DSAUtil retrieve the model and key paraMEters, which are necessary to reconstruct the public key object:

  Listing 3. Retrieving the model and key paraMEters

  public static String getG() throws Exception {;

  return (new String(Base64.encode(DSAPara.getG().toByteArray())));

  };

  public static String getP() throws Exception {;

  return (new String(Base64.encode(DSAPara.getP().toByteArray())));

  };

  public static String getQ() throws Exception {;

  return (new String(Base64.encode(DSAPara.getQ().toByteArray())));

  };

  public static String getY() throws Exception {;

  return (new String(Base64.encode(pubKey.getY().toByteArray())));

  };

  Using the generated private key, the utility class DSASigUtil can get a two-part DSA signature, R and S, from a digest:

  Listing 4. Retrieving the DSA signature

  static public String [] getSignature (String digest) throws Exception {;

  // Sign

  DSASigner signer = new DSASigner();

  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;

  };

  The server encodes the digest, signature, and key paraMEters into ASCII text form and embeds the text in the XML digital signature format, as shown in Listing 5:

  Listing 5. Encoding and embedding in digital signature format

  MEsg>

  <MEsg>Hello WorldMEsg>

 

 

  MEthod

  Algorithm="http://www.w3.org/2000/09/xmldsig#dsa-sha1" />

  Ck1VqNd45QIvq3AZd8XYQLvEhtA=

 

 

  AMfVKyIUyPGdeUCtJxU+N9kQJc2x

  RwGahqpopPx//bMYXzH8dtY0lhA=

 

 

 

 

 

  FgLTXVdxKAmDQtQHkDdFF5zthKSpQhUCzRgXxz7yzxM

  OLYrRoj5D8AXdGLS+5CzT4gu55MbO62dBfyEWKbWTIO

  6E+CuOfa53wvqjMl67tGxc8szgWWA6ZvRwVVVmJ6wqB

  m5hNLr7q1X2eJKQ+u3XYpFflJktOjV8O3zeEPOtsTQ=

 

 

  AOAu2WqVEKGTF8Zcxgde4vxc8f/Z+hk8A10M0AtY2lU

  8CX54dz2MuD6hOmhqGXJxIVlV9085d9D0yHcMv2wl9V

  Vt0/ww+aqFukCKZj9fHgZzq26nOBXMqibDo67J2vfQw

  EZMvCnyBXdS665whjzl5i7ubXu2Su+AqsodnvG9pyYB

 

  AMjJUZy1RnQRqe/22BS83k2Hk8VR

 

  AM/9leouAW7nyON24xeqibMUpVOW8RyzcdNjp9NiPdfm

  HT42BvB4JL/cXx0tCbyHtcR5G+vALoOo7Mh3JJ+/gjx7

  sS8uHNngqx6O6dADrc9VdPvyllNDR0szLja1RTRCIy9M

  8p0dKe/U8iotAj2zctjfbrroMu/fTOBhkvb2gVvR

 

 

 

 

 

  MEsg>

  The verification MIDP application parses the digest, key paraMEters, and signature out of the XML docuMEnt, reconstructs the public key, and uses the following MEthod to validate the signature:

  Listing 6. Validating the signature

  static public boolean verify (String digest,

  String sig_r, String sig_s,

  String key_g, String key_p,

  String key_q, String key_y ) {;

  BigInteger g = new BigInteger( Base64.decode(key_g) );

  BigInteger p = new BigInteger( Base64.decode(key_p) );

  BigInteger q = new BigInteger( Base64.decode(key_q) );

  BigInteger y = new BigInteger( Base64.decode(key_y) );

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

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

  DSAParaMEters DSAPara = new DSAParaMEters(p, q, g);

  DSAPublicKeyParaMEters DSAPubKeyPara = new DSAPublicKeyParaMEters(y,

  DSAPara);

  // Verify

  DSASigner signer = new DSASigner();

  signer.init( false, DSAPubKeyPara );

  boolean result = signer.verifySignature( digest.getBytes(), r, s );

  return result;

  };

  An elliptical curve DSA signature example

  In the ECDSASigUtil class, you first define the elliptical curve model you plan to use, as shown in Listing 7:

  Listing 7. Defining the elliptical curve model

  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");

  The ECDSASigUtil.generateKeys() MEthod generates random key pairs using the model in Listing 7. As MEntioned earlier, this step is normally done offline by a central certificate authority.

  Listing 8. Generating the random key pairs using the model in Listing 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();

  The public key is characterized by a paraMEter Q, and it is retrieved by the pubKey.getQ() MEthod. To avoid confusion with the model paraMEter q, you use QQ in the MEthod and XML eleMEnt naMEs for capital Q. Listing 9 show the MEthods in the ECDSAUtil class. These MEthods retrieve the model and key paraMEters, which are necessary to reconstruct the public key object.

  Listing 9. ECDSAUtil MEthods for retrieving model and key paraMEters

  // 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)));

  };

  Using the generated private key, the utility class ECDSASigUtil can get a two-part DSA signature, R and S, from a digest:

  Listing 10. Retrieving the DSA signature

  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;

  };

  The server encodes the digest, signature, and key paraMEters into ASCII text form and embeds the text in XML digital signature format. As in the retrieval MEthod naME, the public key paraMEter Q is noted as QQ to differentiate it from the key paraMEter q, in the corresponding XML eleMEnt, as shown in Listing 11:

  Listing 11. Encoding and embedding in digital signature format

  MEsg>

  <MEsg>Hello WorldMEsg>

 

 

  MEthod

  Algorithm="http://www.w3.org/2000/09/xmldsig#dsa-sha1" />

  Ck1VqNd45QIvq3AZd8XYQLvEhtA=

 

 

  NK/EIL2lrbFFCThnEuYlUWzh6IEfMsts

  AMEJDecKWrQO6Eeehl3het+FlDDL4IedCA==

 

 

 

 

  AwCiF5uG+DII/x1XTq84fLm4eGN2fED1PYc=

  AP////////////////////7//////////w==

  AP////////////////////7//////////A==

  ZCEFGeWcgOcPp+mrciQwSf643uzBRrmx

  AP///////////////5ne+DYUa8mxtNIoMQ==

  AxiNqA6wMJD2fL8g60OhiAD0/wr9gv8QEg==

 

 

 

 

  MEsg>

  The verification MIDP application parses the digest, key paraMEters, and signature out of the XML docuMEnt, reconstructs the public key, and uses the MEthod shown in Listing 12 to validate the signature:

  Listing 12. Validating the signature

  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;

  };

  An RSA signature example

  The RSA algorithm only has one model paraMEter, Exponent:

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

  The RSASigUtil.generateKeys() MEthod generates random key pairs using Exponent. Again, this step is normally done offline by a central certificate authority.

  Listing 13. Generating random key pairs

  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();

  The public key is characterized by a paraMEter, Modulus, and it is retrieved by the pubKey.getModulus() MEthod. Listing 14 shows the MEthods in the RSAUtil class. These MEthods retrieve Exponent and Modulus, the model and key paraMEters, which are necessary to reconstruct the public key object.

  Listing 14. RSAUtil MEthods for retrieving model and key paraMEters

  // Public key specific paraMEter.

  public static String getMod() throws Exception {;

  return (new String(Base64.encode(pubKey.getModulus().toByteArray())));

  };

  // General key paraMEter. pubExp is the saME as pubKey.getExponent()

  public static String getPubExp() throws Exception {;

  return (new String(Base64.encode(pubExp.toByteArray())));

  };

  Using the generated private key, the utility class RSASigUtil can get a byte array RSA signature from a digest:

  Listing 15. Getting the byte array RSA signature

  static public String getSignature (String MEsg) throws Exception {;

  SHA1Digest digEng = new SHA1Digest();

  RSAEngine rsaEng = new RSAEngine();

  PSSSigner signer = new PSSSigner(rsaEng, digEng, 64);

  signer.init(true, privKey);

  byte [] sig = signer.generateSignature( MEsg.getBytes() );

  String result = new String( Base64.encode(sig) );

  return result;

  };

  The server encodes the digest, signature, and key paraMEters into ASCII text form and embeds the text in XML digital signature format:

  Listing 16. Encoding and embedding in digital signature format

  MEsg>

  <MEsg>Hello WorldMEsg>

 

 

  MEthod Algorithm="rsa-sha1" />

  Ck1VqNd45QIvq3AZd8XYQLvEhtA=

 

 

  IhJ/UMitJX7sWbzhnG8UKIdDYiZ0mfOUoAwemGiG08C

  WcQ3cUszgJXoIclHW/LN7w54w2FQyLStB+hPKASEC6r

  OjjgTBs6pwhjHCh2XxWx7hS7fdi9/Qk/ybH6xYGaeaZ

  3oHDBjFz3hEDtrvBYcHn3keCavncE22idRX7kBl8Do=

 

 

 

 

 

  AKT1SyxSm4uT1zYWEPY9IaFY7vDhpkIM7FZeIQ

  OGnKeSEE5d3sPfONkCiHfO2oe4x6jNCXg/ngRi

  tmixBkjfKgHzF4trZZtNQZjfzAgcXGljzp9MD2

  ZEWQbHKvMZvZyJVrT2SlxLzusxWLwXdacprIDG

  bqDAmldBOBpkmrUdPpF9

 

  EQ==

 

 

 

 

  MEsg>

  The verification MIDP application parses the digest, key paraMEters, and signature out of the XML docuMEnt, reconstructs the public key, and uses the following MEthod to validate the signature:

  Listing 17. Validating the signature

  static public boolean verify (String MEsg, String signature,

  String mod, String pubExp) {;

  BigInteger modulus = new BigInteger( Base64.decode(mod) );

  BigInteger exponent = new BigInteger( Base64.decode(pubExp) );

  SHA1Digest digEng = new SHA1Digest();

  RSAEngine rsaEng = new RSAEngine();

  RSAKeyParaMEters pubKey = new RSAKeyParaMEters(false, modulus, exponent);

  PSSSigner signer = new PSSSigner(rsaEng, digEng, 64);

  signer.init(false, pubKey);

  boolean res = signer.verifySignature( MEsg.getBytes(),

  Base64.decode(signature) );

  return res;

  };

  Performance concerns

  My tests show that XML parsing and digest generation on wireless devices are both very fast. The main performance bottleneck, as expected, is the slow public key algorithms.

  The Bouncy Castle Crypto package provides several signer classes using DSA, RSA, and ECC algorithms to sign and verify MEssages. However, not all of them are practical in real-world devices. Because the Bouncy Castle Crypto package is based purely on the Java language, it relies on the slow JVM to perform even the most intensive big integer mathematical operations without special optimization.

  As a result, only the RSA algorithm gives an acceptable performance, and it is barely acceptable. It can verify a simple digital signature with a 1024-bit public key in slightly more than a minute on a 16MHz Palm VII device. The performance can be improved by choosing a weaker key. But even so, the verification process must run as a background thread in any real-world application to avoid user interface lockup.

  DSA and ECC algorithm performances are completely unacceptable in their current impleMEntations. A DSA signature with a 1024-bit key and an ECC signature with a 192-bit key take more than an hour to verify on standard Palm VII MIDP.

  The performance problems strongly suggest that we need JVMs optimized for big integer mathematical operations and public key algorithms. The JVM must also take advantage of available special hardware and underlying OS features to accelerate security-related math operations. Public key algorithms are used at the handshakes in secure connections such as HTTPS. Many current MIDP VMs can support the HTTPS protocol with reasonable performances. The MIDP4Palm VM can make use of Palm OS''''s underlying inethttps protocol to establish secure connections. It is conceivable that future VMs and core language libraries will not only optimize public key operations associated with secure connections, but also make the optimization available to general security functions such as digital signature.

  Wrapup

  In this article, you learned the importance of security in wireless Web services and illustrated techniques to process XML digital signatures on both the wireless and the Web services sides. I used the pure Java impleMEntation of Bouncy Castle Java cryptography package to handle digital signatures. Of all the algorithms Bouncy Castle offers, only the RSA algorithm offers marginally acceptable performance on wireless devices. However, future advanceMEnt in MIDP runtiME environMEnt could make digital signatures more readily available to mobile users.

<script type="text/javascript"><!-- google_ad_client = "pub-2947489232296736"; /* 728x15, 创建于 08-4-23MSDN */ google_ad_slot = "3624277373"; google_ad_width = 728; google_ad_height = 15; //--> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
<script type="text/javascript"><!-- google_ad_client = "pub-2947489232296736"; /* 160x600, 创建于 08-4-23MSDN */ google_ad_slot = "4367022601"; google_ad_width = 160; google_ad_height = 600; //--> </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
阅读更多
个人分类: xml ajax
想对作者说点什么? 我来说一句

Java移动通信程序设计-J2ME MIDP

2008年12月21日 1.21MB 下载

Core J2ME Technology & MIDP

2007年10月14日 5.61MB 下载

J2ME MIDP 货币转换器

2007年07月15日 9KB 下载

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭