/* * Licensed to the Apache Software Foundation (ASF) under one or more contributor license * agreements. See the NOTICE file distributed with this work for additional information regarding * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance with the License. You may obtain a * copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package org.apache.geode.distributed.internal.membership.gms.messenger; import static org.mockito.Mockito.*; import org.apache.geode.distributed.ConfigurationProperties; import org.apache.geode.distributed.internal.DistributionConfig; import org.apache.geode.distributed.internal.DistributionConfigImpl; import org.apache.geode.distributed.internal.DistributionManager; import org.apache.geode.distributed.internal.membership.InternalDistributedMember; import org.apache.geode.distributed.internal.membership.NetView; import org.apache.geode.distributed.internal.membership.gms.ServiceConfig; import org.apache.geode.distributed.internal.membership.gms.Services; import org.apache.geode.internal.admin.remote.RemoteTransportConfig; import org.apache.geode.test.junit.categories.IntegrationTest; import org.apache.geode.test.junit.categories.MembershipTest; import org.junit.Assert; import org.junit.Test; import java.math.BigInteger; import java.security.Key; import java.security.KeyPair; import java.security.KeyPairGenerator; import org.junit.experimental.categories.Category; import java.util.Arrays; import java.util.LinkedList; import java.util.List; import java.util.Properties; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import javax.crypto.KeyAgreement; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.spec.DHParameterSpec; @Category({IntegrationTest.class, MembershipTest.class}) public class GMSEncryptJUnitTest { Services services; InternalDistributedMember mockMembers[]; NetView netView; private void initMocks() throws Exception { initMocks("AES:128"); } private void initMocks(String algo) throws Exception { Properties nonDefault = new Properties(); nonDefault.put(ConfigurationProperties.SECURITY_UDP_DHALGO, algo); DistributionConfigImpl config = new DistributionConfigImpl(nonDefault); RemoteTransportConfig tconfig = new RemoteTransportConfig(config, DistributionManager.NORMAL_DM_TYPE); ServiceConfig serviceConfig = new ServiceConfig(tconfig, config); services = mock(Services.class); when(services.getConfig()).thenReturn(serviceConfig); mockMembers = new InternalDistributedMember[4]; for (int i = 0; i < mockMembers.length; i++) { mockMembers[i] = new InternalDistributedMember("localhost", 8888 + i); } int viewId = 1; List<InternalDistributedMember> mbrs = new LinkedList<>(); mbrs.add(mockMembers[0]); mbrs.add(mockMembers[1]); mbrs.add(mockMembers[2]); // prepare the view netView = new NetView(mockMembers[0], viewId, mbrs); } String[] algos = new String[] {"AES", "Blowfish", "DES", "DESede"}; @Test public void testOneMemberCanDecryptAnothersMessage() throws Exception { for (String algo : algos) { initMocks(algo); GMSEncrypt gmsEncrypt1 = new GMSEncrypt(services, mockMembers[1]); // this will be the sender GMSEncrypt gmsEncrypt2 = new GMSEncrypt(services, mockMembers[2]); // this will be the // receiver // establish the public keys for the sender and receiver netView.setPublicKey(mockMembers[1], gmsEncrypt1.getPublicKeyBytes()); netView.setPublicKey(mockMembers[2], gmsEncrypt2.getPublicKeyBytes()); gmsEncrypt1.installView(netView, mockMembers[1]); gmsEncrypt2.installView(netView, mockMembers[2]); // sender encrypts a message, so use receiver's public key String ch = "Hello world"; byte[] challenge = ch.getBytes(); byte[] encryptedChallenge = gmsEncrypt1.encryptData(challenge, mockMembers[2]); // receiver decrypts the message using the sender's public key byte[] decryptBytes = gmsEncrypt2.decryptData(encryptedChallenge, mockMembers[1]); // now send a response String response = "Hello yourself!"; byte[] responseBytes = response.getBytes(); byte[] encryptedResponse = gmsEncrypt2.encryptData(responseBytes, mockMembers[1]); // receiver decodes the response byte[] decryptedResponse = gmsEncrypt1.decryptData(encryptedResponse, mockMembers[2]); Assert.assertFalse(Arrays.equals(challenge, encryptedChallenge)); Assert.assertTrue(Arrays.equals(challenge, decryptBytes)); Assert.assertFalse(Arrays.equals(responseBytes, encryptedResponse)); Assert.assertTrue(Arrays.equals(responseBytes, decryptedResponse)); } } @Test public void testOneMemberCanDecryptAnothersMessageMultithreaded() throws Exception { initMocks(); final int runs = 100000; final GMSEncrypt gmsEncrypt1 = new GMSEncrypt(services, mockMembers[1]); // this will be the // sender final GMSEncrypt gmsEncrypt2 = new GMSEncrypt(services, mockMembers[2]); // this will be the // receiver // establish the public keys for the sender and receiver netView.setPublicKey(mockMembers[1], gmsEncrypt1.getPublicKeyBytes()); netView.setPublicKey(mockMembers[2], gmsEncrypt2.getPublicKeyBytes()); gmsEncrypt1.installView(netView, mockMembers[1]); gmsEncrypt2.installView(netView, mockMembers[2]); int nthreads = 20; ExecutorService executorService = Executors.newFixedThreadPool(nthreads); final CountDownLatch countDownLatch = new CountDownLatch(nthreads); for (int j = 0; j < nthreads; j++) executorService.execute(new Runnable() { public void run() { // sender encrypts a message, so use receiver's public key try { int count = 0; for (int i = 0; i < runs; i++) { // System.out.println("another run " + i + " threadid " + // Thread.currentThread().getId()); String ch = "Hello world"; byte[] challenge = ch.getBytes(); byte[] encryptedChallenge = gmsEncrypt1.encryptData(challenge, mockMembers[2]); // receiver decrypts the message using the sender's public key byte[] decryptBytes = gmsEncrypt2.decryptData(encryptedChallenge, mockMembers[1]); // now send a response String response = "Hello yourself!"; byte[] responseBytes = response.getBytes(); byte[] encryptedResponse = gmsEncrypt2.encryptData(responseBytes, mockMembers[1]); // receiver decodes the response byte[] decryptedResponse = gmsEncrypt1.decryptData(encryptedResponse, mockMembers[2]); Assert.assertFalse(Arrays.equals(challenge, encryptedChallenge)); Assert.assertTrue(Arrays.equals(challenge, decryptBytes)); Assert.assertFalse(Arrays.equals(responseBytes, encryptedResponse)); Assert.assertTrue(Arrays.equals(responseBytes, decryptedResponse)); count++; } Assert.assertEquals(runs, count); countDownLatch.countDown(); } catch (Exception e) { e.printStackTrace(); } } }); countDownLatch.await(); executorService.shutdown(); } @Test public void testPublicKeyPrivateKeyFromSameMember() throws Exception { initMocks(); GMSEncrypt gmsEncrypt1 = new GMSEncrypt(services, mockMembers[1]); // this will be the sender GMSEncrypt gmsEncrypt2 = new GMSEncrypt(services, mockMembers[2]); // this will be the receiver gmsEncrypt1 = gmsEncrypt1.clone(); gmsEncrypt2 = gmsEncrypt2.clone(); // establish the public keys for the sender and receiver netView.setPublicKey(mockMembers[1], gmsEncrypt1.getPublicKeyBytes()); netView.setPublicKey(mockMembers[2], gmsEncrypt2.getPublicKeyBytes()); gmsEncrypt1.installView(netView, mockMembers[1]); gmsEncrypt2.installView(netView, mockMembers[2]); // sender encrypts a message, so use receiver's public key String ch = "Hello world"; byte[] challenge = ch.getBytes(); byte[] encryptedChallenge = gmsEncrypt1.encryptData(challenge, mockMembers[2]); // receiver decrypts the message using the sender's public key byte[] decryptBytes = gmsEncrypt2.decryptData(encryptedChallenge, mockMembers[1]); // now send a response String response = "Hello yourself!"; byte[] responseBytes = response.getBytes(); byte[] encryptedResponse = gmsEncrypt2.encryptData(responseBytes, mockMembers[1]); // receiver decodes the response byte[] decryptedResponse = gmsEncrypt1.decryptData(encryptedResponse, mockMembers[2]); Assert.assertFalse(Arrays.equals(challenge, encryptedChallenge)); Assert.assertTrue(Arrays.equals(challenge, decryptBytes)); Assert.assertFalse(Arrays.equals(responseBytes, encryptedResponse)); Assert.assertTrue(Arrays.equals(responseBytes, decryptedResponse)); } @Test public void testForClusterSecretKey() throws Exception { initMocks(); GMSEncrypt gmsEncrypt1 = new GMSEncrypt(services, mockMembers[1]); // this will be the sender gmsEncrypt1.initClusterSecretKey(); // establish the public keys for the sender and receiver netView.setPublicKey(mockMembers[1], gmsEncrypt1.getPublicKeyBytes()); gmsEncrypt1.installView(netView, mockMembers[1]); // sender encrypts a message, so use receiver's public key String ch = "Hello world"; byte[] challenge = ch.getBytes(); byte[] encryptedChallenge = gmsEncrypt1.encryptData(challenge); // receiver decrypts the message using the sender's public key byte[] decryptBytes = gmsEncrypt1.decryptData(encryptedChallenge); Assert.assertFalse(Arrays.equals(challenge, encryptedChallenge)); Assert.assertTrue(Arrays.equals(challenge, decryptBytes)); } @Test public void testForClusterSecretKeyFromOtherMember() throws Exception { for (String algo : algos) { initMocks(algo); final GMSEncrypt gmsEncrypt1 = new GMSEncrypt(services, mockMembers[1]); // this will be the // sender gmsEncrypt1.initClusterSecretKey(); final GMSEncrypt gmsEncrypt2 = new GMSEncrypt(services, mockMembers[2]); // this will be the // sender // establish the public keys for the sender and receiver netView.setPublicKey(mockMembers[1], gmsEncrypt1.getPublicKeyBytes()); netView.setPublicKey(mockMembers[2], gmsEncrypt2.getPublicKeyBytes()); gmsEncrypt1.installView(netView, mockMembers[1]); byte[] secretBytes = gmsEncrypt1.getClusterSecretKey(); gmsEncrypt2.addClusterKey(secretBytes); gmsEncrypt2.installView(netView, mockMembers[1]); // sender encrypts a message, so use receiver's public key String ch = "Hello world"; byte[] challenge = ch.getBytes(); byte[] encryptedChallenge = gmsEncrypt1.encryptData(challenge); // receiver decrypts the message using the sender's public key byte[] decryptBytes = gmsEncrypt2.decryptData(encryptedChallenge); // now send a response String response = "Hello yourself!"; byte[] responseBytes = response.getBytes(); byte[] encryptedResponse = gmsEncrypt2.encryptData(responseBytes); // receiver decodes the response byte[] decryptedResponse = gmsEncrypt1.decryptData(encryptedResponse); Assert.assertFalse(Arrays.equals(challenge, encryptedChallenge)); Assert.assertTrue(Arrays.equals(challenge, decryptBytes)); Assert.assertFalse(Arrays.equals(responseBytes, encryptedResponse)); Assert.assertTrue(Arrays.equals(responseBytes, decryptedResponse)); } } @Test public void testForClusterSecretKeyFromOtherMemberMultipleThreads() throws Exception { initMocks(); final GMSEncrypt gmsEncrypt1 = new GMSEncrypt(services, mockMembers[1]); // this will be the // sender Thread.currentThread().sleep(100); gmsEncrypt1.initClusterSecretKey(); final GMSEncrypt gmsEncrypt2 = new GMSEncrypt(services, mockMembers[2]); // this will be the // sender // establish the public keys for the sender and receiver netView.setPublicKey(mockMembers[1], gmsEncrypt1.getPublicKeyBytes()); netView.setPublicKey(mockMembers[2], gmsEncrypt2.getPublicKeyBytes()); gmsEncrypt1.installView(netView, mockMembers[1]); byte[] secretBytes = gmsEncrypt1.getClusterSecretKey(); gmsEncrypt2.addClusterKey(secretBytes); gmsEncrypt2.installView(netView, mockMembers[1]); final int runs = 100000; int nthreads = 20; ExecutorService executorService = Executors.newFixedThreadPool(nthreads); final CountDownLatch countDownLatch = new CountDownLatch(nthreads); for (int j = 0; j < nthreads; j++) executorService.execute(new Runnable() { public void run() { // sender encrypts a message, so use receiver's public key try { int count = 0; for (int i = 0; i < runs; i++) { // System.out.println("run " + i + " threadid " + Thread.currentThread().getId()); String ch = "Hello world"; byte[] challenge = ch.getBytes(); byte[] encryptedChallenge = gmsEncrypt1.encryptData(challenge); // receiver decrypts the message using the sender's public key byte[] decryptBytes = gmsEncrypt2.decryptData(encryptedChallenge); // now send a response String response = "Hello yourself!"; byte[] responseBytes = response.getBytes(); byte[] encryptedResponse = gmsEncrypt2.encryptData(responseBytes); // receiver decodes the response byte[] decryptedResponse = gmsEncrypt1.decryptData(encryptedResponse); Assert.assertFalse(Arrays.equals(challenge, encryptedChallenge)); Assert.assertTrue(Arrays.equals(challenge, decryptBytes)); Assert.assertFalse(Arrays.equals(responseBytes, encryptedResponse)); Assert.assertTrue(Arrays.equals(responseBytes, decryptedResponse)); count++; } Assert.assertEquals(runs, count); countDownLatch.countDown(); } catch (Exception e) { e.printStackTrace(); } } }); countDownLatch.await(); executorService.shutdown(); } @Test public void testDHAlgo() throws Exception { DHParameterSpec dhSkipParamSpec; System.out.println("Using SKIP Diffie-Hellman parameters"); dhSkipParamSpec = new DHParameterSpec(skip1024Modulus, skip1024Base); // Alice creates her own DH key pair System.out.println("ALICE: Generate DH keypair ..."); KeyPairGenerator aliceKpairGen = KeyPairGenerator.getInstance("DH"); aliceKpairGen.initialize(dhSkipParamSpec); KeyPair aliceKpair = aliceKpairGen.generateKeyPair(); // Bob creates his own DH key pair System.out.println("BOB: Generate DH keypair ..."); KeyPairGenerator bobKpairGen = KeyPairGenerator.getInstance("DH"); bobKpairGen.initialize(dhSkipParamSpec); KeyPair bobKpair = bobKpairGen.generateKeyPair(); // Carol creates her own DH key pair System.out.println("CAROL: Generate DH keypair ..."); KeyPairGenerator carolKpairGen = KeyPairGenerator.getInstance("DH"); carolKpairGen.initialize(dhSkipParamSpec); KeyPair carolKpair = carolKpairGen.generateKeyPair(); // Alice initialize System.out.println("ALICE: Initialize ..."); KeyAgreement aliceKeyAgree = KeyAgreement.getInstance("DH"); aliceKeyAgree.init(aliceKpair.getPrivate()); // Bob initialize System.out.println("BOB: Initialize ..."); KeyAgreement bobKeyAgree = KeyAgreement.getInstance("DH"); bobKeyAgree.init(bobKpair.getPrivate()); // Carol initialize System.out.println("CAROL: Initialize ..."); KeyAgreement carolKeyAgree = KeyAgreement.getInstance("DH"); carolKeyAgree.init(carolKpair.getPrivate()); // Alice uses Carol's public key Key ac = aliceKeyAgree.doPhase(carolKpair.getPublic(), false); // Bob uses Alice's public key Key ba = bobKeyAgree.doPhase(aliceKpair.getPublic(), false); // Carol uses Bob's public key Key cb = carolKeyAgree.doPhase(bobKpair.getPublic(), false); // Alice uses Carol's result from above aliceKeyAgree.doPhase(cb, true); // Bob uses Alice's result from above bobKeyAgree.doPhase(ac, true); // Carol uses Bob's result from above carolKeyAgree.doPhase(ba, true); // Alice, Bob and Carol compute their secrets byte[] aliceSharedSecret = aliceKeyAgree.generateSecret(); System.out.println("Alice secret: " + toHexString(aliceSharedSecret)); byte[] bobSharedSecret = bobKeyAgree.generateSecret(); System.out.println("Bob secret: " + toHexString(bobSharedSecret)); byte[] carolSharedSecret = carolKeyAgree.generateSecret(); System.out.println("Carol secret: " + toHexString(carolSharedSecret)); // Compare Alice and Bob if (!java.util.Arrays.equals(aliceSharedSecret, bobSharedSecret)) throw new Exception("Alice and Bob differ"); System.out.println("Alice and Bob are the same"); // Compare Bob and Carol if (!java.util.Arrays.equals(bobSharedSecret, carolSharedSecret)) throw new Exception("Bob and Carol differ"); System.out.println("Bob and Carol are the same"); } @Test public void testDHAlgo2() throws Exception { DHParameterSpec dhSkipParamSpec; System.out.println("Using SKIP Diffie-Hellman parameters"); dhSkipParamSpec = new DHParameterSpec(skip1024Modulus, skip1024Base); // Alice creates her own DH key pair System.out.println("ALICE: Generate DH keypair ..."); KeyPairGenerator aliceKpairGen = KeyPairGenerator.getInstance("DH"); aliceKpairGen.initialize(dhSkipParamSpec); KeyPair aliceKpair = aliceKpairGen.generateKeyPair(); // Bob creates his own DH key pair System.out.println("BOB: Generate DH keypair ..."); KeyPairGenerator bobKpairGen = KeyPairGenerator.getInstance("DH"); bobKpairGen.initialize(dhSkipParamSpec); KeyPair bobKpair = bobKpairGen.generateKeyPair(); // Alice initialize System.out.println("ALICE: Initialize ..."); KeyAgreement aliceKeyAgree = KeyAgreement.getInstance("DH"); aliceKeyAgree.init(aliceKpair.getPrivate()); // Bob initialize System.out.println("BOB : Initialize ..."); KeyAgreement bobKeyAgree = KeyAgreement.getInstance("DH"); bobKeyAgree.init(bobKpair.getPrivate()); // Alice uses Carol's public key aliceKeyAgree.doPhase(bobKpair.getPublic(), true); // Bob uses Alice's public key bobKeyAgree.doPhase(aliceKpair.getPublic(), true); // Alice, Bob and Carol compute their secrets byte[] aliceSharedSecret = aliceKeyAgree.generateSecret(); System.out.println("Alice secret: " + toHexString(aliceSharedSecret)); byte[] bobSharedSecret = bobKeyAgree.generateSecret(); System.out.println("Bob secret: " + toHexString(bobSharedSecret)); // Compare Alice and Bob if (!java.util.Arrays.equals(aliceSharedSecret, bobSharedSecret)) throw new Exception("Alice and Bob differ"); System.out.println("Alice and Bob are the same"); } @Test public void testDHAlgo3() throws Exception { DHParameterSpec dhSkipParamSpec; System.out.println("Using SKIP Diffie-Hellman parameters"); dhSkipParamSpec = new DHParameterSpec(skip1024Modulus, skip1024Base); // Alice creates her own DH key pair System.out.println("ALICE: Generate DH keypair ..."); KeyPairGenerator aliceKpairGen = KeyPairGenerator.getInstance("DH"); aliceKpairGen.initialize(dhSkipParamSpec); KeyPair aliceKpair = aliceKpairGen.generateKeyPair(); // Bob creates his own DH key pair System.out.println("BOB: Generate DH keypair ..."); KeyPairGenerator bobKpairGen = KeyPairGenerator.getInstance("DH"); bobKpairGen.initialize(dhSkipParamSpec); KeyPair bobKpair = bobKpairGen.generateKeyPair(); // Alice initialize System.out.println("ALICE: Initialize ..."); KeyAgreement aliceKeyAgree = KeyAgreement.getInstance("DH"); aliceKeyAgree.init(aliceKpair.getPrivate()); // Bob initialize System.out.println("BOB : Initialize ..."); KeyAgreement bobKeyAgree = KeyAgreement.getInstance("DH"); bobKeyAgree.init(bobKpair.getPrivate()); // Alice uses Carol's public key aliceKeyAgree.doPhase(bobKpair.getPublic(), true); // Bob uses Alice's public key bobKeyAgree.doPhase(aliceKpair.getPublic(), true); String dhKalgo = "AES"; // Alice, Bob and Carol compute their secrets SecretKey aliceSharedSecret = aliceKeyAgree.generateSecret(dhKalgo); System.out.println("Alice secret: " + toHexString(aliceSharedSecret.getEncoded())); SecretKey bobSharedSecret = bobKeyAgree.generateSecret(dhKalgo); System.out.println("Bob secret: " + toHexString(bobSharedSecret.getEncoded())); // applyMAC(aliceSharedSecret); // applyMAC(bobSharedSecret); // Compare Alice and Bob if (!java.util.Arrays.equals(aliceSharedSecret.getEncoded(), bobSharedSecret.getEncoded())) throw new Exception("Alice and Bob differ"); System.out.println("Alice and Bob are the same"); } private void applyMAC(Key key) throws Exception { SecretKey key2 = new SecretKey() { @Override public String getFormat() { // TODO Auto-generated method stub return key.getFormat(); } @Override public byte[] getEncoded() { // TODO Auto-generated method stub String hitesh = "This is from Hitesh"; byte[] secbytes = hitesh.getBytes(); byte[] origsecret = key.getEncoded(); byte[] ns = new byte[origsecret.length + secbytes.length]; System.arraycopy(origsecret, 0, ns, 0, origsecret.length); System.arraycopy(secbytes, 0, ns, origsecret.length, secbytes.length); return ns; } @Override public String getAlgorithm() { // TODO Auto-generated method stub return key.getAlgorithm(); } }; // Generate secret key for HMAC-MD5 // KeyGenerator kg = KeyGenerator.getInstance("HmacMD5"); // SecretKey sk = kg.generateKey(); // Get instance of Mac object implementing HMAC-MD5, and // initialize it with the above secret key System.out.println("Key2 secret " + toHexString(key2.getEncoded())); Mac mac = Mac.getInstance("HmacMD5"); mac.init(key2); byte[] result = mac.doFinal("Hi There".getBytes()); System.out.println("Message Authentication code length: " + mac.getMacLength()); System.out.println("Message Authentication code : " + toHexString(result)); verifyMacBody(mac, result); } private byte[] verifyMacBody(Mac hmac, byte[] encryptedAndMac) throws Exception { byte[] encrypted = new byte[encryptedAndMac.length - hmac.getMacLength()]; System.arraycopy(encryptedAndMac, 0, encrypted, 0, encrypted.length); byte[] remoteMac = new byte[hmac.getMacLength()]; System.arraycopy(encryptedAndMac, encryptedAndMac.length - remoteMac.length, remoteMac, 0, remoteMac.length); byte[] localMac = hmac.doFinal(encrypted); System.out.println("Message Authentication code remoteMac : " + toHexString(remoteMac)); System.out.println("Message Authentication code localMac : " + toHexString(localMac)); if (!Arrays.equals(remoteMac, localMac)) throw new Exception("MAC doesen't match."); return encrypted; } // The 1024 bit Diffie-Hellman modulus values used by SKIP private static final byte skip1024ModulusBytes[] = {(byte) 0xF4, (byte) 0x88, (byte) 0xFD, (byte) 0x58, (byte) 0x4E, (byte) 0x49, (byte) 0xDB, (byte) 0xCD, (byte) 0x20, (byte) 0xB4, (byte) 0x9D, (byte) 0xE4, (byte) 0x91, (byte) 0x07, (byte) 0x36, (byte) 0x6B, (byte) 0x33, (byte) 0x6C, (byte) 0x38, (byte) 0x0D, (byte) 0x45, (byte) 0x1D, (byte) 0x0F, (byte) 0x7C, (byte) 0x88, (byte) 0xB3, (byte) 0x1C, (byte) 0x7C, (byte) 0x5B, (byte) 0x2D, (byte) 0x8E, (byte) 0xF6, (byte) 0xF3, (byte) 0xC9, (byte) 0x23, (byte) 0xC0, (byte) 0x43, (byte) 0xF0, (byte) 0xA5, (byte) 0x5B, (byte) 0x18, (byte) 0x8D, (byte) 0x8E, (byte) 0xBB, (byte) 0x55, (byte) 0x8C, (byte) 0xB8, (byte) 0x5D, (byte) 0x38, (byte) 0xD3, (byte) 0x34, (byte) 0xFD, (byte) 0x7C, (byte) 0x17, (byte) 0x57, (byte) 0x43, (byte) 0xA3, (byte) 0x1D, (byte) 0x18, (byte) 0x6C, (byte) 0xDE, (byte) 0x33, (byte) 0x21, (byte) 0x2C, (byte) 0xB5, (byte) 0x2A, (byte) 0xFF, (byte) 0x3C, (byte) 0xE1, (byte) 0xB1, (byte) 0x29, (byte) 0x40, (byte) 0x18, (byte) 0x11, (byte) 0x8D, (byte) 0x7C, (byte) 0x84, (byte) 0xA7, (byte) 0x0A, (byte) 0x72, (byte) 0xD6, (byte) 0x86, (byte) 0xC4, (byte) 0x03, (byte) 0x19, (byte) 0xC8, (byte) 0x07, (byte) 0x29, (byte) 0x7A, (byte) 0xCA, (byte) 0x95, (byte) 0x0C, (byte) 0xD9, (byte) 0x96, (byte) 0x9F, (byte) 0xAB, (byte) 0xD0, (byte) 0x0A, (byte) 0x50, (byte) 0x9B, (byte) 0x02, (byte) 0x46, (byte) 0xD3, (byte) 0x08, (byte) 0x3D, (byte) 0x66, (byte) 0xA4, (byte) 0x5D, (byte) 0x41, (byte) 0x9F, (byte) 0x9C, (byte) 0x7C, (byte) 0xBD, (byte) 0x89, (byte) 0x4B, (byte) 0x22, (byte) 0x19, (byte) 0x26, (byte) 0xBA, (byte) 0xAB, (byte) 0xA2, (byte) 0x5E, (byte) 0xC3, (byte) 0x55, (byte) 0xE9, (byte) 0x2F, (byte) 0x78, (byte) 0xC7}; // The SKIP 1024 bit modulus private static final BigInteger skip1024Modulus = new BigInteger(1, skip1024ModulusBytes); // The base used with the SKIP 1024 bit modulus private static final BigInteger skip1024Base = BigInteger.valueOf(2); /* * Converts a byte to hex digit and writes to the supplied buffer */ private void byte2hex(byte b, StringBuffer buf) { char[] hexChars = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; int high = ((b & 0xf0) >> 4); int low = (b & 0x0f); buf.append(hexChars[high]); buf.append(hexChars[low]); } /* * Converts a byte array to hex string */ private String toHexString(byte[] block) { StringBuffer buf = new StringBuffer(); int len = block.length; for (int i = 0; i < len; i++) { byte2hex(block[i], buf); if (i < len - 1) { buf.append(":"); } } return buf.toString(); } }