Source Code Cross Referenced for DecryptionManager.java in  » Database-DBMS » db-derby-10.2 » org » apache » derby » impl » drda » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database DBMS » db derby 10.2 » org.apache.derby.impl.drda 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:
003:           Derby - Class org.apache.derby.impl.drda.DecryptionManager
004:
005:           Licensed to the Apache Software Foundation (ASF) under one or more
006:           contributor license agreements.  See the NOTICE file distributed with
007:           this work for additional information regarding copyright ownership.
008:           The ASF licenses this file to You under the Apache License, Version 2.0
009:           (the "License"); you may not use this file except in compliance with
010:           the License.  You may obtain a copy of the License at
011:
012:              http://www.apache.org/licenses/LICENSE-2.0
013:
014:           Unless required by applicable law or agreed to in writing, software
015:           distributed under the License is distributed on an "AS IS" BASIS,
016:           WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017:           See the License for the specific language governing permissions and
018:           limitations under the License.
019:
020:         */
021:
022:        package org.apache.derby.impl.drda;
023:
024:        import java.security.KeyPairGenerator;
025:        import java.security.KeyPair;
026:        import javax.crypto.KeyAgreement;
027:        import javax.crypto.spec.DHParameterSpec;
028:        import javax.crypto.interfaces.DHPublicKey;
029:        import javax.crypto.spec.DHPublicKeySpec;
030:        import javax.crypto.spec.SecretKeySpec;
031:        import javax.crypto.Cipher;
032:        import javax.crypto.spec.IvParameterSpec;
033:        import java.security.spec.AlgorithmParameterSpec;
034:        import java.security.KeyFactory;
035:        import java.security.PublicKey;
036:        import java.sql.SQLException;
037:        import java.math.BigInteger;
038:        import org.apache.derby.shared.common.sanity.SanityManager;
039:
040:        /**
041:         * This class is used to decrypt password and/or userid.
042:         * It uses Diffie_Hellman algorithm to get the publick key and secret key, and then
043:         * DES encryption is done using certain token (based on security mechanism) and 
044:         * this side's own public key. Basically, this class is called when using a security
045:         * mechanism that encrypts user ID and password (eusridpwd). This class uses IBM JCE
046:         * to do Diffie_Hellman algorithm and DES encryption.
047:         */
048:
049:        class DecryptionManager {
050:            // DRDA's Diffie-Hellman agreed public value: prime.
051:            private static final byte modulusBytes__[] = { (byte) 0xC6,
052:                    (byte) 0x21, (byte) 0x12, (byte) 0xD7, (byte) 0x3E,
053:                    (byte) 0xE6, (byte) 0x13, (byte) 0xF0, (byte) 0x94,
054:                    (byte) 0x7A, (byte) 0xB3, (byte) 0x1F, (byte) 0x0F,
055:                    (byte) 0x68, (byte) 0x46, (byte) 0xA1, (byte) 0xBF,
056:                    (byte) 0xF5, (byte) 0xB3, (byte) 0xA4, (byte) 0xCA,
057:                    (byte) 0x0D, (byte) 0x60, (byte) 0xBC, (byte) 0x1E,
058:                    (byte) 0x4C, (byte) 0x7A, (byte) 0x0D, (byte) 0x8C,
059:                    (byte) 0x16, (byte) 0xB3, (byte) 0xE3 };
060:
061:            //the prime value in BigInteger form. It has to be in BigInteger form because this
062:            //is the form used in JCE library.
063:            private static final BigInteger modulus__ = new BigInteger(1,
064:                    modulusBytes__);
065:
066:            //  DRDA's Diffie-Hellman agreed public value: base.
067:            private static final byte baseBytes__[] = { (byte) 0x46,
068:                    (byte) 0x90, (byte) 0xFA, (byte) 0x1F, (byte) 0x7B,
069:                    (byte) 0x9E, (byte) 0x1D, (byte) 0x44, (byte) 0x42,
070:                    (byte) 0xC8, (byte) 0x6C, (byte) 0x91, (byte) 0x14,
071:                    (byte) 0x60, (byte) 0x3F, (byte) 0xDE, (byte) 0xCF,
072:                    (byte) 0x07, (byte) 0x1E, (byte) 0xDC, (byte) 0xEC,
073:                    (byte) 0x5F, (byte) 0x62, (byte) 0x6E, (byte) 0x21,
074:                    (byte) 0xE2, (byte) 0x56, (byte) 0xAE, (byte) 0xD9,
075:                    (byte) 0xEA, (byte) 0x34, (byte) 0xE4 };
076:
077:            // The base value in BigInteger form. It has to be in BigInteger form because
078:            //this is the form used in IBM JCE library.
079:            private static final BigInteger base__ = new BigInteger(1,
080:                    baseBytes__);
081:
082:            //DRDA's Diffie-Hellman agreed exponential length
083:            private static final int exponential_length__ = 255;
084:
085:            private KeyPairGenerator keyPairGenerator_;
086:            private KeyPair keyPair_;
087:            private KeyAgreement keyAgreement_;
088:            private DHParameterSpec paramSpec_;
089:
090:            // Random Number Generator (PRNG) Algorithm
091:            private final static String SHA_1_PRNG_ALGORITHM = "SHA1PRNG";
092:            private final static int SECMEC_USRSSBPWD_SEED_LEN = 8; // Seed length
093:
094:            /**
095:             * EncryptionManager constructor. In this constructor,DHParameterSpec,
096:             * KeyPairGenerator, KeyPair, and KeyAgreement  are initialized.
097:             *
098:             * @throws SQLException that wraps any error
099:             */
100:            DecryptionManager() throws SQLException {
101:                try {
102:                    if (java.security.Security.getProvider("IBMJCE") == null) // IBMJCE is not installed, install it.
103:                        java.security.Security
104:                                .addProvider((java.security.Provider) Class
105:                                        .forName("IBMJCE").newInstance());
106:                    paramSpec_ = new DHParameterSpec(modulus__, base__,
107:                            exponential_length__);
108:                    keyPairGenerator_ = KeyPairGenerator.getInstance("DH",
109:                            "IBMJCE");
110:                    keyPairGenerator_
111:                            .initialize((AlgorithmParameterSpec) paramSpec_);
112:                    keyPair_ = keyPairGenerator_.generateKeyPair();
113:                    keyAgreement_ = KeyAgreement.getInstance("DH", "IBMJCE");
114:                    keyAgreement_.init(keyPair_.getPrivate());
115:                } catch (java.lang.ClassNotFoundException e) {
116:                    throw new SQLException(
117:                            "java.lang.ClassNotFoundException is caught"
118:                                    + " when initializing EncryptionManager '"
119:                                    + e.getMessage() + "'");
120:                } catch (java.lang.IllegalAccessException e) {
121:                    throw new SQLException(
122:                            "java.lang.IllegalAccessException is caught"
123:                                    + " when initializing EncryptionManager '"
124:                                    + e.getMessage() + "'");
125:                } catch (java.lang.InstantiationException e) {
126:                    throw new SQLException(
127:                            "java.lang.InstantiationException is caught"
128:                                    + " when initializing EncryptionManager '"
129:                                    + e.getMessage() + "'");
130:                } catch (java.security.NoSuchProviderException e) {
131:                    throw new SQLException(
132:                            "java.security.NoSuchProviderException is caught"
133:                                    + " when initializing EncryptionManager '"
134:                                    + e.getMessage() + "'");
135:                } catch (java.security.NoSuchAlgorithmException e) {
136:                    throw new SQLException(
137:                            "java.security.NoSuchAlgorithmException is caught"
138:                                    + " when initializing EncryptionManager '"
139:                                    + e.getMessage() + "'");
140:                } catch (java.security.InvalidAlgorithmParameterException e) {
141:                    throw new SQLException(
142:                            "java.security.InvalidAlgorithmParameterException is caught"
143:                                    + " when initializing EncryptionManager '"
144:                                    + e.getMessage() + "'");
145:                }
146:
147:                catch (java.security.InvalidKeyException e) {
148:                    throw new SQLException(
149:                            "java.security.InvalidKeyException is caught"
150:                                    + " when initializing EncryptionManager '"
151:                                    + e.getMessage() + "'");
152:                }
153:            }
154:
155:            /**
156:             * This method generates the public key and returns it. This
157:             * shared public key is the application server's connection key and will
158:             * be exchanged with the application requester's connection key. This connection
159:             * key will be put in the sectkn in ACCSECRD command and send to the application
160:             * requester.
161:             *
162:             * @return  a byte array that is the application server's public key
163:             */
164:            public byte[] obtainPublicKey() {
165:                //The encoded public key
166:                byte[] publicEnc = keyPair_.getPublic().getEncoded();
167:
168:                //we need to get the plain form public key because DRDA accepts plain form
169:                //public key only.
170:                BigInteger aPub = ((DHPublicKey) keyPair_.getPublic()).getY();
171:                byte[] aPubKey = aPub.toByteArray();
172:
173:                //the following lines of code is to adjust the length of the key. PublicKey
174:                //in JCE is in the form of BigInteger and it's a signed value. When tranformed
175:                //to a Byte array form, normally this array is 32 bytes. However, if the
176:                //value happens to take up all 32 X 8 bits and it is positive, an extra
177:                //bit is needed and then a 33 byte array will be returned. Since DRDA can't
178:                //recogize the 33 byte key, we check the length here, if the length is 33,
179:                //we will just trim off the first byte (0) and get the rest of 32 bytes.
180:                if (aPubKey.length == 33 && aPubKey[0] == 0) {
181:                    byte[] newKey = new byte[32];
182:                    for (int i = 0; i < newKey.length; i++)
183:                        newKey[i] = aPubKey[i + 1];
184:                    return newKey;
185:                }
186:
187:                //the following lines of code is to adjust the length of the key. Occasionally,
188:                //the length of the public key is less than 32, the reason of this is that the 0 byte
189:                //in the beginning is somehow not returned. So we check the length here, if the length
190:                //is less than 32, we will pad 0 in the beginning to make the public key 32 bytes
191:                if (aPubKey.length < 32) {
192:                    byte[] newKey = new byte[32];
193:                    int i;
194:                    for (i = 0; i < 32 - aPubKey.length; i++) {
195:                        newKey[i] = 0;
196:                    }
197:                    for (int j = i; j < newKey.length; j++)
198:                        newKey[j] = aPubKey[j - i];
199:                    return newKey;
200:                }
201:                return aPubKey;
202:            }
203:
204:            /**
205:             * This method is used to calculate the decryption token. DES encrypts the
206:             * data using a token and the generated shared private key. The token used
207:             * depends on the type of security mechanism being used:
208:             * USRENCPWD - The userid is used as the token. The USRID is zero-padded to
209:             * 8 bytes if less than 8 bytes or truncated to 8 bytes if greater than 8 bytes.
210:             * EUSRIDPWD - The middle 8 bytes of the server's connection key is used as
211:             * the token.  Decryption needs to use exactly the same token as encryption.
212:             *
213:             * @param  securityMechanism security mechanism
214:             * @param  initVector  userid or server(this side)'s connection key
215:             * @return byte[]  the decryption token
216:             */
217:            private byte[] calculateDecryptionToken(int securityMechanism,
218:                    byte[] initVector) {
219:                byte[] token = new byte[8];
220:
221:                //USRENCPWD, the userid is used as token
222:                if (securityMechanism == 7) {
223:                    if (initVector.length < 8) { //shorter than 8 bytes, zero padded to 8 bytes
224:                        for (int i = 0; i < initVector.length; i++)
225:                            token[i] = initVector[i];
226:                        for (int i = initVector.length; i < 8; i++)
227:                            token[i] = 0;
228:                    } else { //longer than 8 bytes, truncated to 8 bytes
229:                        for (int i = 0; i < 8; i++)
230:                            token[i] = initVector[i];
231:                    }
232:                }
233:                //EUSRIDPWD - The middle 8 bytes of the server's connection key is used as
234:                //the token.
235:                else if (securityMechanism == 9) {
236:                    for (int i = 0; i < 8; i++) {
237:                        token[i] = initVector[i + 12];
238:                    }
239:                }
240:                return token;
241:            }
242:
243:            /**
244:             * This method generates a secret key using the application requester's
245:             * public key, and decrypts the usreid/password with the middle 8 bytes of
246:             * the generated secret key and a decryption token. Then it returns the
247:             * decrypted data in a byte array.
248:             *
249:             * @param cipherText        The byte array form userid/password to decrypt.
250:             * @param securityMechanism security mechanism
251:             * @param initVector        The byte array which is used to calculate the
252:             *                          decryption token for initializing the cipher
253:             * @param sourcePublicKey   application requester (encrypter)'s public key.
254:             * @return the decrypted data (plain text) in a byte array.
255:             */
256:            public byte[] decryptData(byte[] cipherText, int securityMechanism,
257:                    byte[] initVector, byte[] sourcePublicKey)
258:                    throws SQLException {
259:                byte[] plainText = null;
260:                byte[] token = calculateDecryptionToken(securityMechanism,
261:                        initVector);
262:                try {
263:
264:                    //initiate a Diffie_Hellman KeyFactory object.
265:                    KeyFactory keyFac = KeyFactory.getInstance("DH", "IBMJCE");
266:
267:                    //Use server's public key to initiate a DHPublicKeySpec and then use
268:                    //this DHPublicKeySpec to initiate a publicKey object
269:                    BigInteger publicKey = new BigInteger(1, sourcePublicKey);
270:                    DHPublicKeySpec dhKeySpec = new DHPublicKeySpec(publicKey,
271:                            modulus__, base__);
272:                    PublicKey pubKey = keyFac.generatePublic(dhKeySpec);
273:
274:                    //Execute the first phase of DH keyagreement protocal.
275:                    keyAgreement_.doPhase(pubKey, true);
276:
277:                    //generate the shared secret key. The application requestor's shared secret
278:                    //key should be exactly the same as the application server's shared secret
279:                    //key
280:                    byte[] sharedSecret = keyAgreement_.generateSecret();
281:                    byte[] newKey = new byte[32];
282:
283:                    //We adjust the length here. If the length of secret key is 33 and the first byte is 0,
284:                    //we trim off the frist byte. If the length of secret key is less than 32, we will
285:                    //pad 0 to the beginning of the byte array tho make the secret key 32 bytes.
286:                    if (sharedSecret.length == 33 && sharedSecret[0] == 0) {
287:                        for (int i = 0; i < newKey.length; i++)
288:                            newKey[i] = sharedSecret[i + 1];
289:                    }
290:                    if (sharedSecret.length < 32) {
291:                        int i;
292:                        for (i = 0; i < (32 - sharedSecret.length); i++)
293:                            newKey[i] = 0;
294:                        for (int j = i; j < sharedSecret.length; j++)
295:                            newKey[j] = sharedSecret[j - i];
296:                    }
297:
298:                    //The Data Encryption Standard (DES) is going to be used to encrypt userid
299:                    //and password. DES is a block cipher; it encrypts data in 64-bit blocks.
300:                    //DRDA encryption uses DES CBC mode as defined by the FIPS standard
301:                    //DES CBC requires an encryption key and an 8 byte token to encrypt the data.
302:                    //The middle 8 bytes of Diffie-Hellman shared private key is used as the
303:                    //encryption key. The following code retrieves middle 8 bytes of the shared
304:                    //private key.
305:                    byte[] key = new byte[8];
306:
307:                    //if secret key is not 32, we will use the adjust length secret key
308:                    if (sharedSecret.length == 32) {
309:                        for (int i = 0; i < 8; i++)
310:                            key[i] = sharedSecret[i + 12];
311:                    } else if (sharedSecret.length == 33
312:                            || sharedSecret.length < 32) {
313:                        for (int i = 0; i < 8; i++)
314:                            key[i] = newKey[i + 12];
315:                    } else
316:                        throw new SQLException("sharedSecret key length error "
317:                                + sharedSecret.length);
318:
319:                    // make parity bit right, even number of 1's
320:                    byte temp;
321:                    int changeParity;
322:                    for (int i = 0; i < 8; i++) {
323:                        temp = key[i];
324:                        changeParity = 1;
325:                        for (int j = 0; j < 8; j++) {
326:                            if (temp < 0)
327:                                changeParity = 1 - changeParity;
328:                            temp = (byte) (temp << 1);
329:                        }
330:                        if (changeParity == 1) {
331:                            if ((key[i] & 1) != 0)
332:                                key[i] &= 0xfe;
333:                            else
334:                                key[i] |= 1;
335:                        }
336:                    }
337:
338:                    //use this encryption key to initiate a SecretKeySpec object
339:                    SecretKeySpec desKey = new SecretKeySpec(key, "DES");
340:
341:                    //We use DES in CBC mode because this is the mode used in DRDA. The
342:                    //encryption mode has to be consistent for encryption and decryption.
343:                    //CBC mode requires an initialization vector(IV) parameter. In CBC mode
344:                    //we need to initialize the Cipher object with an IV, which can be supplied
345:                    // using the javax.crypto.spec.IvParameterSpec class.
346:                    Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding",
347:                            "IBMJCE");
348:
349:                    //generate a IVParameterSpec object and use it to initiate the
350:                    //Cipher object.
351:                    IvParameterSpec ivParam = new IvParameterSpec(token);
352:
353:                    //initiate the Cipher using encryption mode, encryption key and the
354:                    //IV parameter.
355:                    cipher.init(javax.crypto.Cipher.DECRYPT_MODE, desKey,
356:                            ivParam);
357:
358:                    //Execute the final phase of encryption
359:                    plainText = cipher.doFinal(cipherText);
360:                } catch (java.security.NoSuchProviderException e) {
361:                    throw new SQLException(
362:                            "java.security.NoSuchProviderException is caught "
363:                                    + "when encrypting data '" + e.getMessage()
364:                                    + "'");
365:                } catch (java.security.NoSuchAlgorithmException e) {
366:                    throw new SQLException(
367:                            "java.security.NoSuchAlgorithmException is caught "
368:                                    + "when encrypting data '" + e.getMessage()
369:                                    + "'");
370:                } catch (java.security.spec.InvalidKeySpecException e) {
371:                    throw new SQLException(
372:                            "java.security.InvalidKeySpecException is caught "
373:                                    + "when encrypting data");
374:                } catch (java.security.InvalidKeyException e) {
375:                    throw new SQLException(
376:                            "java.security.InvalidKeyException is caught "
377:                                    + "when encrypting data '" + e.getMessage()
378:                                    + "'");
379:                } catch (javax.crypto.NoSuchPaddingException e) {
380:                    throw new SQLException(
381:                            "javax.crypto.NoSuchPaddingException is caught "
382:                                    + "when encrypting data '" + e.getMessage()
383:                                    + "'");
384:                } catch (javax.crypto.BadPaddingException e) {
385:                    throw new SQLException(
386:                            "javax.crypto.BadPaddingException is caught "
387:                                    + "when encrypting data '" + e.getMessage()
388:                                    + "'");
389:                } catch (java.security.InvalidAlgorithmParameterException e) {
390:                    throw new SQLException(
391:                            "java.security.InvalidAlgorithmParameterException is caught "
392:                                    + "when encrypting data '" + e.getMessage()
393:                                    + "'");
394:                } catch (javax.crypto.IllegalBlockSizeException e) {
395:                    throw new SQLException(
396:                            "javax.crypto.IllegalBlockSizeException is caught "
397:                                    + "when encrypting data '" + e.getMessage()
398:                                    + "'");
399:                }
400:                return plainText;
401:            }
402:
403:            /**
404:             * This method generates an 8-Byte random seed.
405:             *
406:             * Required for the SECMEC_USRSSBPWD security mechanism
407:             *
408:             * @return a random 8-Byte seed.
409:             */
410:            protected static byte[] generateSeed() throws SQLException {
411:                java.security.SecureRandom secureRandom = null;
412:                try {
413:                    // We're verifying that we can instantiate a randon number
414:                    // generator (PRNG).
415:                    secureRandom = java.security.SecureRandom
416:                            .getInstance(SHA_1_PRNG_ALGORITHM);
417:                } catch (java.security.NoSuchAlgorithmException nsae) {
418:                    throw new SQLException(
419:                            "java.security.NoSuchAlgorithmException is caught"
420:                                    + " when initializing DecryptionManager '"
421:                                    + nsae.getMessage() + "'");
422:                }
423:                byte randomSeedBytes[] = new byte[SECMEC_USRSSBPWD_SEED_LEN];
424:                secureRandom.setSeed(secureRandom
425:                        .generateSeed(SECMEC_USRSSBPWD_SEED_LEN));
426:                secureRandom.nextBytes(randomSeedBytes);
427:                // Return the 8-byte generated random seed
428:                return randomSeedBytes;
429:            }
430:
431:            /*********************************************************************
432:             * RESOLVE:                                                          *
433:             * The methods and static vars below should go into some 'shared'    *
434:             * package when the capability is put back in (StringUtil.java).     *
435:             *********************************************************************/
436:
437:            private static char[] hex_table = { '0', '1', '2', '3', '4', '5',
438:                    '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
439:
440:            /**
441:                Convert a byte array to a String with a hexidecimal format.
442:                The String may be converted back to a byte array using fromHexString.
443:                <BR>
444:                For each byte (b) two characaters are generated, the first character
445:                represents the high nibble (4 bits) in hexidecimal (<code>b & 0xf0</code>),
446:                the second character represents the low nibble (<code>b & 0x0f</code>).
447:            	<BR>
448:                The byte at <code>data[offset]</code> is represented by the first two characters in the returned String.
449:
450:                @param	data	byte array
451:                @param	offset	starting byte (zero based) to convert.
452:                @param	length	number of bytes to convert.
453:
454:                @return the String (with hexidecimal format) form of the byte array
455:             */
456:            protected static String toHexString(byte[] data, int offset,
457:                    int length) {
458:                StringBuffer s = new StringBuffer(length * 2);
459:                int end = offset + length;
460:
461:                for (int i = offset; i < end; i++) {
462:                    int high_nibble = (data[i] & 0xf0) >>> 4;
463:                    int low_nibble = (data[i] & 0x0f);
464:                    s.append(hex_table[high_nibble]);
465:                    s.append(hex_table[low_nibble]);
466:                }
467:
468:                return s.toString();
469:            }
470:
471:            /**
472:            
473:                Convert a string into a byte array in hex format.
474:                <BR>
475:                For each character (b) two bytes are generated, the first byte 
476:                represents the high nibble (4 bits) in hexidecimal (<code>b & 0xf0</code>),
477:                the second byte 
478:                represents the low nibble (<code>b & 0x0f</code>).
479:                <BR>
480:                The character at <code>str.charAt(0)</code> is represented by the first two bytes 
481:                in the returned String.
482:
483:                @param	str string 
484:                @param	offset	starting character (zero based) to convert.
485:                @param	length	number of characters to convert.
486:
487:                @return the byte[]  (with hexidecimal format) form of the string (str) 
488:             */
489:            protected static byte[] toHexByte(String str, int offset, int length) {
490:                byte[] data = new byte[(length - offset) * 2];
491:                int end = offset + length;
492:
493:                for (int i = offset; i < end; i++) {
494:                    char ch = str.charAt(i);
495:                    int high_nibble = (ch & 0xf0) >>> 4;
496:                    int low_nibble = (ch & 0x0f);
497:                    data[i] = (byte) high_nibble;
498:                    data[i + 1] = (byte) low_nibble;
499:                }
500:                return data;
501:            }
502:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.