Conducting Diffie Hellman between Java and Crypto++ (C++) - java
I want to encrypt some data between a c++ client and a java server. Searching the web I found crypto++ to use on the client and on the java side to use the KeyAgreement built in java class(btw, I already have bouncycastle jar in my project, I can use it if it's somehow better than the built in one).
I was able to perform DH on on every side with itself as an example, but due to key sizes I cannot make them to agree on a secret key.
My C++ code:
// g++ -g3 -ggdb -O0 -I. -I/usr/include/cryptopp dh-agree.cpp -o dh-agree.exe -lcryptopp -lpthread
// g++ -g -O2 -I. -I/usr/include/cryptopp dh-agree.cpp -o dh-agree.exe -lcryptopp -lpthread
#include <iostream>
using std::cout;
using std::cerr;
using std::endl;
#include <sys/socket.h>
#include <sys/types.h>
#include <stdio.h>
#include <errno.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string>
using std::string;
#include <stdexcept>
using std::runtime_error;
#include "osrng.h"
using CryptoPP::AutoSeededRandomPool;
#include "integer.h"
using CryptoPP::Integer;
#include "nbtheory.h"
using CryptoPP::ModularExponentiation;
#include "dh.h"
using CryptoPP::DH;
#include "secblock.h"
using CryptoPP::SecByteBlock;
#include <hex.h>
using CryptoPP::HexEncoder;
#include <filters.h>
using CryptoPP::StringSink;
int main(int argc, char** argv)
{
try
{
// RFC 5114, 1024-bit MODP Group with 160-bit Prime Order Subgroup
// http://tools.ietf.org/html/rfc5114#section-2.1
Integer p("0xB10B8F96A080E01DDE92DE5EAE5D54EC52C99FBCFB06A3C6"
"9A6A9DCA52D23B616073E28675A23D189838EF1E2EE652C0"
"13ECB4AEA906112324975C3CD49B83BFACCBDD7D90C4BD70"
"98488E9C219A73724EFFD6FAE5644738FAA31A4FF55BCCC0"
"A151AF5F0DC8B4BD45BF37DF365C1A65E68CFDA76D4DA708"
"DF1FB2BC2E4A4371");
Integer g("0xA4D1CBD5C3FD34126765A442EFB99905F8104DD258AC507F"
"D6406CFF14266D31266FEA1E5C41564B777E690F5504F213"
"160217B4B01B886A5E91547F9E2749F4D7FBD7D3B9A92EE1"
"909D0D2263F80A76A6A24C087A091F531DBF0A0169B6A28A"
"D662A4D18E73AFA32D779D5918D08BC8858F4DCEF97C2A24"
"855E6EEB22B3B2E5");
Integer q("0xF518AA8781A8DF278ABA4E7D64B7CB9D49462353");
// Schnorr Group primes are of the form p = rq + 1, p and q prime. They
// provide a subgroup order. In the case of 1024-bit MODP Group, the
// security level is 80 bits (based on the 160-bit prime order subgroup).
// For a compare/contrast of using the maximum security level, see
// dh-agree.zip. Also see http://www.cryptopp.com/wiki/Diffie-Hellman
// and http://www.cryptopp.com/wiki/Security_level .
DH dh;
AutoSeededRandomPool rnd;
dh.AccessGroupParameters().Initialize(p, q, g);
if(!dh.GetGroupParameters().ValidateGroup(rnd, 3))
throw runtime_error("Failed to validate prime and generator");
size_t count = 0;
p = dh.GetGroupParameters().GetModulus();
q = dh.GetGroupParameters().GetSubgroupOrder();
g = dh.GetGroupParameters().GetGenerator();
// http://groups.google.com/group/sci.crypt/browse_thread/thread/7dc7eeb04a09f0ce
Integer v = ModularExponentiation(g, q, p);
if(v != Integer::One())
throw runtime_error("Failed to verify order of the subgroup");
//////////////////////////////////////////////////////////////
SecByteBlock priv(dh.PrivateKeyLength());
SecByteBlock pub(dh.PublicKeyLength());
dh.GenerateKeyPair(rnd, priv, pub);
printf("lengths: %d %d\n",dh.PrivateKeyLength(),dh.PublicKeyLength());
byte* pubData = pub.data();
for(int j = 0; j < pub.size()-1; j++)
printf("%02X:", pubData[j]);
printf("%02X\n", pubData[pub.size()-1]);
// Send pub to Java
sendData(pub.data(),pub.size());
// Read pubB from Java
byte pubBbytes[10000];
int n = readData(pubBbytes,sizeof(pubBbytes));
SecByteBlock pubB(pubBbytes,n);
//////////////////////////////////////////////////////////////
SecByteBlock sharedA(dh.AgreedValueLength());
if(!dh.Agree(sharedA, priv, pubB))
throw runtime_error("Failed to reach shared secret (1A)");
//////////////////////////////////////////////////////////////
Integer a;
a.Decode(sharedA.BytePtr(), sharedA.SizeInBytes());
cout << "Shared secret (A): " << std::hex << a << endl;
}
catch(const CryptoPP::Exception& e)
{
cerr << e.what() << endl;
return -2;
}
catch(const std::exception& e)
{
cerr << e.what() << endl;
return -1;
}
return 0;
}
Server code in Java:
package test;
/*
* Copyright (c) 1997, 2001, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.KeyAgreement;
import javax.crypto.spec.DHParameterSpec;
/**
* This program executes the Diffie-Hellman key agreement protocol
* between 2 parties: Alice and Bob.
*
* By default, preconfigured parameters (1024-bit prime modulus and base
* generator used by SKIP) are used.
* If this program is called with the "-gen" option, a new set of
* parameters is created.
*/
public class DHKeyAgreement2 {
private DHKeyAgreement2() {}
public final static String sP = "B10B8F96A080E01DDE92DE5EAE5D54EC52C99FBCFB06A3C6" +
"9A6A9DCA52D23B616073E28675A23D189838EF1E2EE652C0" +
"13ECB4AEA906112324975C3CD49B83BFACCBDD7D90C4BD70" +
"98488E9C219A73724EFFD6FAE5644738FAA31A4FF55BCCC0" +
"A151AF5F0DC8B4BD45BF37DF365C1A65E68CFDA76D4DA708" +
"DF1FB2BC2E4A4371";
public final static String sG = "A4D1CBD5C3FD34126765A442EFB99905F8104DD258AC507F" +
"D6406CFF14266D31266FEA1E5C41564B777E690F5504F213" +
"160217B4B01B886A5E91547F9E2749F4D7FBD7D3B9A92EE1" +
"909D0D2263F80A76A6A24C087A091F531DBF0A0169B6A28A" +
"D662A4D18E73AFA32D779D5918D08BC8858F4DCEF97C2A24" +
"855E6EEB22B3B2E5";
public static void main(String argv[]) {
try {
DHKeyAgreement2 keyAgree = new DHKeyAgreement2();
keyAgree.run();
} catch (Exception e) {
System.err.println("Error: " + e);
System.exit(1);
}
}
private void run() throws Exception {
DHParameterSpec dhSkipParamSpec;
// use some pre-generated, default DH parameters
System.out.println("Using SKIP Diffie-Hellman parameters");
BigInteger p = new BigInteger(sP,16);
BigInteger g = new BigInteger(sG,16);
System.out.println("P " + sP.length() + " is: " + toHexString(p.toByteArray()));
System.out.println("G " + sG.length() + " is: " + toHexString(g.toByteArray()));
dhSkipParamSpec = new DHParameterSpec(p,g);
/*
* Alice creates her own DH key pair, using the DH parameters from
* above
*/
System.out.println("ALICE: Generate DH keypair ...");
KeyPairGenerator aliceKpairGen = KeyPairGenerator.getInstance("DH");
aliceKpairGen.initialize(dhSkipParamSpec);
KeyPair aliceKpair = aliceKpairGen.generateKeyPair();
// Alice creates and initializes her DH KeyAgreement object
System.out.println("ALICE: Initialization ...");
KeyAgreement aliceKeyAgree = KeyAgreement.getInstance("DH");
aliceKeyAgree.init(aliceKpair.getPrivate());
// Alice encodes her public key, and sends it over to Bob.
byte[] alicePubKeyEnc = aliceKpair.getPublic().getEncoded();
byte[] alicePrivKeyEnc = aliceKpair.getPrivate().getEncoded();
System.out.println("Alice pub key size: " + alicePubKeyEnc.length);
System.out.println("Alice pub key: " + toHexString(alicePubKeyEnc));
System.out.println("Alice priv key size: " + alicePrivKeyEnc.length);
System.out.println("Alice priv key: " + toHexString(alicePrivKeyEnc));
ServerSocket ss = new ServerSocket(5454);
Socket accept = ss.accept();
byte[] bobPubKeyEnc = readByteArrayFromSocket(accept);
System.out.println("Read bob's pubkey: " + toHexString(bobPubKeyEnc));
sendByteArrayToBob(alicePubKeyEnc);
System.out.println("Sent Alice's pubkey");
/*
* Alice uses Bob's public key for the first (and only) phase
* of her version of the DH
* protocol.
* Before she can do so, she has to instantiate a DH public key
* from Bob's encoded key material.
*/
KeyFactory aliceKeyFac = KeyFactory.getInstance("DH");
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(bobPubKeyEnc);
PublicKey bobPubKey = aliceKeyFac.generatePublic(x509KeySpec);
System.out.println("ALICE: Execute PHASE1 ...");
aliceKeyAgree.doPhase(bobPubKey, true);
/*
* At this stage, both Alice and Bob have completed the DH key
* agreement protocol.
* Both generate the (same) shared secret.
*/
byte[] aliceSharedSecret = aliceKeyAgree.generateSecret();
int aliceLen = aliceSharedSecret.length;
System.out.println("Alice secret: " +
toHexString(aliceSharedSecret));
}
}
My output from C++:
lengths: 20 128
77:61:FD:93:D9:23:38:41:6D:B0:9B:F8:7A:FB:CE:CA:0E:DF:7D:0A:95:F6:B4:55:FF:64:32:03:2C:B5:9C:47:05:06:FF:1B:72:F3:C6:8A:91:68:13:98:DE:56:0C:D6:02:30:C2:4B:DB:AD:0A:B3:7D:2A:7E:DD:13:A8:7C:97:4A:46:79:6A:85:C7:5B:79:29:D8:E5:2B:F4:59:21:B3:29:EA:6A:2F:FB:70:A1:C8:FD:5C:31:E1:92:A9:B0:67:74:65:3D:C1:1B:33:4B:DE:1C:EB:1E:A1:3A:36:29:0F:DF:A2:FA:5D:DA:69:DC:6D:00:D7:76:95:3A:FD:7D:76
sent 128 bytes, remaining 0
Failed to reach shared secret (1A)
And output from Java:
Using SKIP Diffie-Hellman parameters
P 256 is: 00:B1:0B:8F:96:A0:80:E0:1D:DE:92:DE:5E:AE:5D:54:EC:52:C9:9F:BC:FB:06:A3:C6:9A:6A:9D:CA:52:D2:3B:61:60:73:E2:86:75:A2:3D:18:98:38:EF:1E:2E:E6:52:C0:13:EC:B4:AE:A9:06:11:23:24:97:5C:3C:D4:9B:83:BF:AC:CB:DD:7D:90:C4:BD:70:98:48:8E:9C:21:9A:73:72:4E:FF:D6:FA:E5:64:47:38:FA:A3:1A:4F:F5:5B:CC:C0:A1:51:AF:5F:0D:C8:B4:BD:45:BF:37:DF:36:5C:1A:65:E6:8C:FD:A7:6D:4D:A7:08:DF:1F:B2:BC:2E:4A:43:71
G 256 is: 00:A4:D1:CB:D5:C3:FD:34:12:67:65:A4:42:EF:B9:99:05:F8:10:4D:D2:58:AC:50:7F:D6:40:6C:FF:14:26:6D:31:26:6F:EA:1E:5C:41:56:4B:77:7E:69:0F:55:04:F2:13:16:02:17:B4:B0:1B:88:6A:5E:91:54:7F:9E:27:49:F4:D7:FB:D7:D3:B9:A9:2E:E1:90:9D:0D:22:63:F8:0A:76:A6:A2:4C:08:7A:09:1F:53:1D:BF:0A:01:69:B6:A2:8A:D6:62:A4:D1:8E:73:AF:A3:2D:77:9D:59:18:D0:8B:C8:85:8F:4D:CE:F9:7C:2A:24:85:5E:6E:EB:22:B3:B2:E5
ALICE: Generate DH keypair ...
ALICE: Initialization ...
Alice pub key size: 426
Alice pub key: 30:82:01:A6:30:82:01:1B:06:09:2A:86:48:86:F7:0D:01:03:01:30:82:01:0C:02:81:81:00:B1:0B:8F:96:A0:80:E0:1D:DE:92:DE:5E:AE:5D:54:EC:52:C9:9F:BC:FB:06:A3:C6:9A:6A:9D:CA:52:D2:3B:61:60:73:E2:86:75:A2:3D:18:98:38:EF:1E:2E:E6:52:C0:13:EC:B4:AE:A9:06:11:23:24:97:5C:3C:D4:9B:83:BF:AC:CB:DD:7D:90:C4:BD:70:98:48:8E:9C:21:9A:73:72:4E:FF:D6:FA:E5:64:47:38:FA:A3:1A:4F:F5:5B:CC:C0:A1:51:AF:5F:0D:C8:B4:BD:45:BF:37:DF:36:5C:1A:65:E6:8C:FD:A7:6D:4D:A7:08:DF:1F:B2:BC:2E:4A:43:71:02:81:81:00:A4:D1:CB:D5:C3:FD:34:12:67:65:A4:42:EF:B9:99:05:F8:10:4D:D2:58:AC:50:7F:D6:40:6C:FF:14:26:6D:31:26:6F:EA:1E:5C:41:56:4B:77:7E:69:0F:55:04:F2:13:16:02:17:B4:B0:1B:88:6A:5E:91:54:7F:9E:27:49:F4:D7:FB:D7:D3:B9:A9:2E:E1:90:9D:0D:22:63:F8:0A:76:A6:A2:4C:08:7A:09:1F:53:1D:BF:0A:01:69:B6:A2:8A:D6:62:A4:D1:8E:73:AF:A3:2D:77:9D:59:18:D0:8B:C8:85:8F:4D:CE:F9:7C:2A:24:85:5E:6E:EB:22:B3:B2:E5:02:02:02:00:03:81:84:00:02:81:80:25:E7:BD:24:57:C9:59:EE:E0:EC:7A:F3:D6:22:1C:84:68:52:D9:19:40:5F:1B:C6:CB:A9:3A:42:BF:AB:3C:C2:EC:6F:BC:F9:F9:B2:70:AC:A2:E5:CE:36:FC:06:4F:2D:B3:4F:B5:25:D9:59:AD:D6:AD:B6:17:FA:09:76:AE:89:99:91:52:9B:E0:10:1D:9F:AC:50:AF:02:6D:25:F6:E8:DD:B8:6C:51:17:44:59:98:52:4B:E9:75:E1:D1:26:FE:EA:73:EF:C7:89:7F:70:A8:ED:6F:57:28:A4:0F:1B:F8:21:7D:A5:A2:59:B9:74:42:42:45:BA:EC:E2:53:B3:C4
Alice priv key size: 362
Alice priv key: 30:82:01:66:02:01:00:30:82:01:1B:06:09:2A:86:48:86:F7:0D:01:03:01:30:82:01:0C:02:81:81:00:B1:0B:8F:96:A0:80:E0:1D:DE:92:DE:5E:AE:5D:54:EC:52:C9:9F:BC:FB:06:A3:C6:9A:6A:9D:CA:52:D2:3B:61:60:73:E2:86:75:A2:3D:18:98:38:EF:1E:2E:E6:52:C0:13:EC:B4:AE:A9:06:11:23:24:97:5C:3C:D4:9B:83:BF:AC:CB:DD:7D:90:C4:BD:70:98:48:8E:9C:21:9A:73:72:4E:FF:D6:FA:E5:64:47:38:FA:A3:1A:4F:F5:5B:CC:C0:A1:51:AF:5F:0D:C8:B4:BD:45:BF:37:DF:36:5C:1A:65:E6:8C:FD:A7:6D:4D:A7:08:DF:1F:B2:BC:2E:4A:43:71:02:81:81:00:A4:D1:CB:D5:C3:FD:34:12:67:65:A4:42:EF:B9:99:05:F8:10:4D:D2:58:AC:50:7F:D6:40:6C:FF:14:26:6D:31:26:6F:EA:1E:5C:41:56:4B:77:7E:69:0F:55:04:F2:13:16:02:17:B4:B0:1B:88:6A:5E:91:54:7F:9E:27:49:F4:D7:FB:D7:D3:B9:A9:2E:E1:90:9D:0D:22:63:F8:0A:76:A6:A2:4C:08:7A:09:1F:53:1D:BF:0A:01:69:B6:A2:8A:D6:62:A4:D1:8E:73:AF:A3:2D:77:9D:59:18:D0:8B:C8:85:8F:4D:CE:F9:7C:2A:24:85:5E:6E:EB:22:B3:B2:E5:02:02:02:00:04:42:02:40:3C:16:B6:8F:73:CD:9D:0F:19:D5:A7:54:61:FC:A9:AF:3E:79:78:B8:5E:3E:3D:58:52:2F:95:5E:0D:3F:E0:19:92:17:22:B4:06:9A:E4:ED:9D:55:54:3F:1F:DE:20:36:31:5A:AC:58:FB:A3:C2:7E:65:31:A4:F0:43:37:A2:37
Read 128 bytes
Read bob's pubkey: 77:61:FD:93:D9:23:38:41:6D:B0:9B:F8:7A:FB:CE:CA:0E:DF:7D:0A:95:F6:B4:55:FF:64:32:03:2C:B5:9C:47:05:06:FF:1B:72:F3:C6:8A:91:68:13:98:DE:56:0C:D6:02:30:C2:4B:DB:AD:0A:B3:7D:2A:7E:DD:13:A8:7C:97:4A:46:79:6A:85:C7:5B:79:29:D8:E5:2B:F4:59:21:B3:29:EA:6A:2F:FB:70:A1:C8:FD:5C:31:E1:92:A9:B0:67:74:65:3D:C1:1B:33:4B:DE:1C:EB:1E:A1:3A:36:29:0F:DF:A2:FA:5D:DA:69:DC:6D:00:D7:76:95:3A:FD:7D:76
Sent Alice's pubkey
Error: java.security.spec.InvalidKeySpecException: Inappropriate key specification
Seems like altough I use the same G and P in both programs, the keys generated in C++ are 128\20 byte long (public\private) while in java they are 426\362 byte long. I was wondering where I can set the desired key length in crypto++ but yet to discover that. Also I removed some helper function from the codes above, so I guess copy-paste and trying to compile them won't work. If anyone will actually want to do that I will submit my complete code.
Thanks
Related
Difference between Go DSA and Java DSA [closed]
Closed. This question needs details or clarity. It is not currently accepting answers. Want to improve this question? Add details and clarify the problem by editing this post. Closed 1 year ago. Improve this question Go generates a signature using a DSA private key Java verifies first step result using the DSA public key Java should return true, but returns false package main import ( "crypto/dsa" "crypto/rand" "encoding/asn1" "encoding/hex" "fmt" "golang.org/x/crypto/ssh" "math/big" ) func main() { // a dsa private key pemData := []byte("-----BEGIN DSA PRIVATE KEY-----\n" + "MIIBvAIBAAKBgQD9f1OBHXUSKVLfSpwu7OTn9hG3UjzvRADDHj+AtlEmaUVdQCJR\n" + "+1k9jVj6v8X1ujD2y5tVbNeBO4AdNG/yZmC3a5lQpaSfn+gEexAiwk+7qdf+t8Yb\n" + "+DtX58aophUPBPuD9tPFHsMCNVQTWhaRMvZ1864rYdcq7/IiAxmd0UgBxwIVAJdg\n" + "UI8VIwvMspK5gqLrhAvwWBz1AoGBAPfhoIXWmz3ey7yrXDa4V7l5lK+7+jrqgvlX\n" + "TAs9B4JnUVlXjrrUWU/mcQcQgYC0SRZxI+hMKBYTt88JMozIpuE8FnqLVHyNKOCj\n" + "rh4rs6Z1kW6jfwv6ITVi8ftiegEkO8yk8b6oUZCJqIPf4VrlnwaSi2ZegHtVJWQB\n" + "TDv+z0kqAoGBAIb9o0KPsjAdzjK571e1Mx7ZhEyJGrcxHiN2sW8IztEbqrKKiMxp\n" + "NlTwm234uBdtzVHE3uDWZpfHPMIRmwBjCYDFRowWWVRdhdFXZlpCyp1gMWqJ11dh\n" + "3FI3+O43DevRSyyuLRVCNQ1J3iVgwY5ndRpZU7n6y8DPH4/4EBT7KvnVAhR4Vwun\n" + "Fhu/+4AGaVeMEa814I3dqg==\n" + "-----END DSA PRIVATE KEY-----") // parse dsa p, _ := ssh.ParseRawPrivateKey(pemData) pp := p.(*dsa.PrivateKey) // orign data hashed := []byte{1} r, s, _ := dsa.Sign(rand.Reader, pp, hashed) type dsaSignature struct { R, S *big.Int } var ss dsaSignature ss.S = s ss.R = r signatureBytes, _ := asn1.Marshal(ss) // print sign fmt.Println(hex.EncodeToString(signatureBytes)) } Java reads the DSA public key and initialize a signer Java verify first step sign result returns false #Test public void ttt() throws InvalidKeySpecException, NoSuchAlgorithmException, InvalidKeyException, SignatureException { // DSA public key String pubKey = "-----BEGIN PUBLIC KEY-----\n" + "MIIBuDCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9E\n" + "AMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f\n" + "6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv\n" + "8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuEC/BYHPUCgYEA9+GghdabPd7LvKtc\n" + "NrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3zwky\n" + "jMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/h\n" + "WuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYUAAoGBAIb9o0KPsjAdzjK571e1Mx7ZhEyJ\n" + "GrcxHiN2sW8IztEbqrKKiMxpNlTwm234uBdtzVHE3uDWZpfHPMIRmwBjCYDFRowW\n" + "WVRdhdFXZlpCyp1gMWqJ11dh3FI3+O43DevRSyyuLRVCNQ1J3iVgwY5ndRpZU7n6\n" + "y8DPH4/4EBT7KvnV\n" + "-----END PUBLIC KEY-----"; String publicKeyPEM = pubKey .replace("-----BEGIN PUBLIC KEY-----\n", "") .replaceAll(System.lineSeparator(), "") .replace("-----END PUBLIC KEY-----", ""); byte[] publicEncoded = Base64.decodeBase64(publicKeyPEM); KeyFactory keyFactory1 = KeyFactory.getInstance("DSA"); X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicEncoded); DSAPublicKey pubKeyy = (DSAPublicKey) keyFactory1.generatePublic(publicKeySpec); // init signer Signature sig1 = Signature.getInstance("DSA"); sig1.initVerify(pubKeyy); sig1.update(new byte[]{1}); // verify first result System.out.println(sig1.verify(HexUtil.decodeHex("first step result"))); } i tred to use NONEwithDSA within the Java implementation but it didnt do it Signature sig1 = Signature.getInstance("NONEwithDSA"); java.security.SignatureException: Data for RawDSA must be exactly 20 bytes long i tred to use SHA1withDSA within the Java implementation but it didnt do it Signature sig1 = Signature.getInstance("SHA1withDSA"); returns false
In Java the (Signature) algorithm name DSA is an alias for SHA1withDSA, i.e. the original FIPS186-0 algorithm. This is not the same as the nonstandard 'raw' primitive apparently implemented by Go. NONEwithDSA is indeed the correct Java name for what you want, but the implementation in the 'standard' (SUN) provider is something of a kludge that requires exactly 20 bytes of data, not more or less, because that was the size of the SHA1 hash which was the only standard hash for DSA prior to FIPS186-3. If you (have or can get and) use the BouncyCastle provider, it does not have this restriction, and should work for your code changed to NONEwithDSA (and either the code or security config modified so that BC is selected as the provider, of course). If you don't use Bouncy, I think you'll have to code the algorithm yourself; I don't think there's any way to get the SUN implementation to do what you want. Although it would be better to sign a properly-sized hash as specified in the standard, not raw data, and then you could use the Java providers as specified and designed.
Using openssh public key (ecdsa-sha2-nistp256) with Java Security
Is there a Java library/example to read an openssh format ecdsa public key to a JCE PublicKey in Java? I want to use EC for JWT . The format I'm trying to read is as per authorized_keys, or Github API (e.g. https://api.github.com/users/davidcarboni/keys): ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK8hPtB72/sfYgNw1WTska2DNOJFx+QhUxuV6OLINSD2ty+6gxcM8yZrvMqWdMePGRb2cGh8L/0bGOk+64IQ/pM= I've found this answer, which is fine for RSA and DSS: Using public key from authorized_keys with Java security, and this discussion of the openssh format for ECDSA: https://security.stackexchange.com/questions/129910/ecdsa-why-do-ssh-keygen-and-java-generated-public-keys-have-different-sizes However I'm getting lost trying to adapt the RSS/DSA code for ECDSA - I'm not sure how to set up an ECPublicKeySpec. It needs ECPoint, EllipticCurve, ECParameterSpec, ECField. The openssh format only contains two integers, which makes sense for ECPoint, but I don't know how to set up the rest. I've been poking around a bunch of libraries, including jsch, sshj, ssh-tools and good old Bouncycastle. The closest I have is: com.jcraft.jsch.KeyPair load = com.jcraft.jsch.KeyPair.load(jsch, null, bytes[openSshKey]); Which loads the key fine, but doesn't get me to a JCE PublicKey - just a byte[] getPublicKeyBlob() method. Am I missing something obvious?
I've found a way to do this using Bouncycastle (but would like to find a JCE way). Adapting the code from Using public key from authorized_keys with Java security, and refering to RFC 5656, section 3.1, the following block added to decodePublicKey will parse the single BigInt value Q, which is "the public key encoded from an elliptic curve point": if (type.startsWith("ecdsa-sha2-") && (type.endsWith("nistp256") || type.endsWith("nistp384") || type.endsWith("nistp521"))) { // Based on RFC 5656, section 3.1 (https://www.rfc-editor.org/rfc/rfc5656#section-3.1) // The string [identifier] is the identifier of the elliptic curve // domain parameters. The format of this string is specified in // Section 6.1 (https://www.rfc-editor.org/rfc/rfc5656#section-6.1). // Information on the REQUIRED and RECOMMENDED sets of // elliptic curve domain parameters for use with this algorithm can be // found in Section 10 (https://www.rfc-editor.org/rfc/rfc5656#section-10). String identifier = decodeType(); if (!type.endsWith(identifier)) { throw new IllegalArgumentException("Invalid identifier " + identifier + " for key type " + type + "."); } // Q is the public key encoded from an elliptic curve point into an // octet string as defined in Section 2.3.3 of [SEC1]; // (https://www.rfc-editor.org/rfc/rfc5656#ref-SEC1) // point compression MAY be used. BigInteger q = decodeBigInt(); ECPublicKey keyBC = getKeyBC(q, identifier); return keyBC; } The solution I've found for getting from Q to an ECPublicKey is the following, using the Bouncycastle API (credit to Generate ECPublicKey from ECPrivateKey for providing the starting point): ECPublicKey getKeyBC(BigInteger q, String identifier) { // https://stackoverflow.com/questions/42639620/generate-ecpublickey-from-ecprivatekey try { // This only works with the Bouncycastle library: Security.addProvider(new BouncyCastleProvider()); // http://www.bouncycastle.org/wiki/pages/viewpage.action?pageId=362269#SupportedCurves(ECDSAandECGOST)-NIST(aliasesforSECcurves) String name = identifier.replace("nist", "sec") + "r1"; KeyFactory keyFactory = KeyFactory.getInstance("ECDSA", "BC"); ECNamedCurveParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec(name); ECPoint point = ecSpec.getCurve().decodePoint(q.toByteArray()); ECPublicKeySpec pubSpec = new ECPublicKeySpec(point, ecSpec); ECPublicKey publicKey = (ECPublicKey) keyFactory.generatePublic(pubSpec); return publicKey; } catch (NoSuchAlgorithmException | InvalidKeySpecException | NoSuchProviderException e) { throw new RuntimeException(e); } } That gets you from an openssh format elliptic curve public key (ssh-keygen -t ecdsa -b [256|384|521]) to a JCE ECPublicKey.
For completeness, here's the code I've gone with. It's nearly-pure JCE, with a sprinkling of Bouncycastle inside helper methods (this updates the example code in Using public key from authorized_keys with Java security): ... } else if (type.startsWith("ecdsa-sha2-") && (type.endsWith("nistp256") || type.endsWith("nistp384") || type.endsWith("nistp521"))) { // Based on RFC 5656, section 3.1 (https://tools.ietf.org/html/rfc5656#section-3.1) String identifier = decodeType(); BigInteger q = decodeBigInt(); ECPoint ecPoint = getECPoint(q, identifier); ECParameterSpec ecParameterSpec = getECParameterSpec(identifier); ECPublicKeySpec spec = new ECPublicKeySpec(ecPoint, ecParameterSpec); return KeyFactory.getInstance("EC").generatePublic(spec); } ... /** * Provides a means to get from a parsed Q value to the X and Y point values. * that can be used to create and ECPoint compatible with ECPublicKeySpec. * * #param q According to RFC 5656: * "Q is the public key encoded from an elliptic curve point into an octet string" * #param identifier According to RFC 5656: * "The string [identifier] is the identifier of the elliptic curve domain parameters." * #return An ECPoint suitable for creating a JCE ECPublicKeySpec. */ ECPoint getECPoint(BigInteger q, String identifier) { String name = identifier.replace("nist", "sec") + "r1"; ECNamedCurveParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec(name); org.bouncycastle.math.ec.ECPoint point = ecSpec.getCurve().decodePoint(q.toByteArray()); BigInteger x = point.getAffineXCoord().toBigInteger(); BigInteger y = point.getAffineYCoord().toBigInteger(); System.out.println("BC x = " + x); System.out.println("BC y = " + y); return new ECPoint(x, y); } /** * Gets the curve parameters for the given key type identifier. * * #param identifier According to RFC 5656: * "The string [identifier] is the identifier of the elliptic curve domain parameters." * #return An ECParameterSpec suitable for creating a JCE ECPublicKeySpec. */ ECParameterSpec getECParameterSpec(String identifier) { try { // http://www.bouncycastle.org/wiki/pages/viewpage.action?pageId=362269#SupportedCurves(ECDSAandECGOST)-NIST(aliasesforSECcurves) String name = identifier.replace("nist", "sec") + "r1"; AlgorithmParameters parameters = AlgorithmParameters.getInstance("EC"); parameters.init(new ECGenParameterSpec(name)); return parameters.getParameterSpec(ECParameterSpec.class); } catch (InvalidParameterSpecException | NoSuchAlgorithmException e) { throw new IllegalArgumentException("Unable to get parameter spec for identifier " + identifier, e); } }
ECC decryption corresponding to ECIES from Bouncy Castle
I am trying to decrypt files in Ruby which were encrypted with ECIES in Java using BouncyCastle as JCE Provider ECIES Algorithm P-384 named curve In Java the encryption was done using Cipher.doFinal() and then written to a file. A test case implements encryption and decryption. In Ruby all i can find is the OpenSSL::PKey::EC implementation, but this does not seem to have encryption or decryption but only Verify and Sign. Does anyone know of a way to do this in Ruby? My worst case scenario would be to simply call the Java decryption routing from Ruby, but that really isn't the way i want to go.
ECC decryption corresponding to ECIES from Bouncy Castle ECIES is Shoup's Integrated Encryption System. Its much more than simply EC encrypt and decrypt. You can find Shoup's paper at A Proposal for an ISO Standard for Public Key Encryption. In Ruby all i can find is the OpenSSL::PKey::EC implementation OpenSSL does not have an ECIES implementation. It does not have an implementation of Abdalla, Bellare, and Rogaway's DHAES, either. My worst case scenario would be to simply call the Java decryption routing from Ruby, but that really isn't the way i want to go. You will probably have to shell out to Java. Related (sorry about wandering into C++): Crypto++ also has ECIES. However, the Bouncy Castle and Crypto++ implementations do not inter-operate out of the box. See Problem with the way gfpcrypt HMAC's the encoding parameters' length in DHAES_MODE on the Crypto++ mailing list. The interop issue is a difference in the size of a label that gets hashed as a security parameter when using DHAES_MODE. Crypto++ uses a 8-octet label, while Bouncy Castle uses a 4-octet label. I don't recall who was/is correct. At the bottom of the Crypto++ page on Elliptic Curve Integrated Encryption Scheme, there's a patch available based on Jessie Wilson's comments at cryptopp-ecies-bc.zip. Download it, apply it, and use the ECIES_BC class rather than the ECIES class. Here's the essence of the patch. BC_COMPAT is a template parameter. diff --git a/gfpcrypt.h b/gfpcrypt.h index 7af993f..18ea104 100644 --- a/gfpcrypt.h +++ b/gfpcrypt.h ## -408,7 +408,9 ## CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_GFP<DL_GroupParameters_DSA>; CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_WithSignaturePairwiseConsistencyTest<DL_PrivateKey_GFP<DL_GroupParameters_DSA>, DSA2<SHA> >; //! the XOR encryption method, for use with DL-based cryptosystems -template <class MAC, bool DHAES_MODE> +// Set BC_COMPAT=true if interop'ing with Bouncy Castle. Thanks to Jesse Wilson and Daniele Perito. +// See https://groups.google.com/d/msg/cryptopp-users/vR8GSL8wxPA/Bf9koUDyZ88J. +template <class MAC, bool DHAES_MODE, bool BC_COMPAT = false> class DL_EncryptionAlgorithm_Xor : public DL_SymmetricEncryptionAlgorithm { public: ## -442,9 +444,17 ## public: mac.Update(encodingParameters.begin(), encodingParameters.size()); if (DHAES_MODE) { - byte L[8] = {0,0,0,0}; - PutWord(false, BIG_ENDIAN_ORDER, L+4, word32(encodingParameters.size())); - mac.Update(L, 8); + if (BC_COMPAT) { + byte L[4]; + PutWord(false, BIG_ENDIAN_ORDER, L, word32(8 * encodingParameters.size())); + mac.Update(L, 4); + } + else + { + byte L[8] = {0,0,0,0}; + PutWord(false, BIG_ENDIAN_ORDER, L+4, word32(encodingParameters.size())); + mac.Update(L, 8); + } } mac.Final(ciphertext + plaintextLength); } ## -471,9 +481,17 ## public: mac.Update(encodingParameters.begin(), encodingParameters.size()); if (DHAES_MODE) { - byte L[8] = {0,0,0,0}; - PutWord(false, BIG_ENDIAN_ORDER, L+4, word32(encodingParameters.size())); - mac.Update(L, 8); + if (BC_COMPAT) { + byte L[4]; + PutWord(false, BIG_ENDIAN_ORDER, L, word32(8 * encodingParameters.size())); + mac.Update(L, 4); + } + else + { + byte L[8] = {0,0,0,0}; + PutWord(false, BIG_ENDIAN_ORDER, L+4, word32(encodingParameters.size())); + mac.Update(L, 8); + } } if (!mac.Verify(ciphertext + plaintextLength)) return DecodingResult();
How to query Ldap to get user's attributes in result and use it in auto fill in JSF2.0 form
Can someone please guide/help me in setting up the LDAP connection with Glassfish v3.1.2 using JNDI . I googled on this topic only to find people setting up and using ldap in Glassfish to authenticate the user. Whereas, I need to fetch user data which is to be displayed on my JSF forms and for auto complete during new entires creation on those forms. I am bit confused. Is Ldap connection in Glassfish only used for authenticating and setting the realm? Ok I found something while googling for the ways to query. But my extremely limited knowledge still hindering my progress. So here is the code I found on http://www.myjeeva.com/2012/05/querying-active-directory-using-java/ Active Directory /** * The MIT License * * Copyright (c) 2010-2012 www.myjeeva.com * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * */ package com.LdapSearchDaoBean; import java.util.Properties; import java.util.logging.Logger; import javax.naming.Context; import javax.naming.NamingEnumeration; import javax.naming.NamingException; import javax.naming.directory.DirContext; import javax.naming.directory.InitialDirContext; import javax.naming.directory.SearchControls; import javax.naming.directory.SearchResult; /** * Query Active Directory using Java * * #filename ActiveDirectory.java * #author Jeevanandam Madanagopal * #copyright © 2010-2012 www.myjeeva.com */ public class ActiveDirectory { // Logger private static final Logger LOG = Logger.getLogger(ActiveDirectory.class.getName()); //required private variables private Properties properties; private DirContext dirContext; private SearchControls searchCtls; private String[] returnAttributes = { "sAMAccountName", "givenName", "cn", "mail" }; private String domainBase; private String baseFilter = "(&((&(objectCategory=Person)(objectClass=User)))"; /** * constructor with parameter for initializing a LDAP context * * #param username a {#link java.lang.String} object - username to establish a LDAP connection * #param password a {#link java.lang.String} object - password to establish a LDAP connection * #param domainController a {#link java.lang.String} object - domain controller name for LDAP connection */ public ActiveDirectory(String username, String password, String domainController) { properties = new Properties(); properties.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); properties.put(Context.PROVIDER_URL, "LDAP://" + domainController); properties.put(Context.SECURITY_PRINCIPAL, username + "#" + domainController); properties.put(Context.SECURITY_CREDENTIALS, password); //initializing active directory LDAP connection try { dirContext = new InitialDirContext(properties); } catch (NamingException e) { LOG.severe(e.getMessage()); } //default domain base for search domainBase = getDomainBase(domainController); //initializing search controls searchCtls = new SearchControls(); searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE); searchCtls.setReturningAttributes(returnAttributes); } /** * search the Active directory by username/email id for given search base * * #param searchValue a {#link java.lang.String} object - search value used for AD search for eg. username or email * #param searchBy a {#link java.lang.String} object - scope of search by username or by email id * #param searchBase a {#link java.lang.String} object - search base value for scope tree for eg. DC=myjeeva,DC=com * #return search result a {#link javax.naming.NamingEnumeration} object - active directory search result * #throws NamingException */ public NamingEnumeration<SearchResult> searchUser(String searchValue, String searchBy, String searchBase) throws NamingException { String filter = getFilter(searchValue, searchBy); String base = (null == searchBase) ? domainBase : getDomainBase(searchBase); // for eg.: "DC=myjeeva,DC=com"; return this.dirContext.search(base, filter, this.searchCtls); } /** * closes the LDAP connection with Domain controller */ public void closeLdapConnection(){ try { if(dirContext != null) dirContext.close(); } catch (NamingException e) { LOG.severe(e.getMessage()); } } /** * active directory filter string value * * #param searchValue a {#link java.lang.String} object - search value of username/email id for active directory * #param searchBy a {#link java.lang.String} object - scope of search by username or email id * #return a {#link java.lang.String} object - filter string */ private String getFilter(String searchValue, String searchBy) { String filter = this.baseFilter; if(searchBy.equals("email")) { filter += "(mail=" + searchValue + "))"; } else if(searchBy.equals("username")) { filter += "(samaccountname=" + searchValue + "))"; } return filter; } /** * creating a domain base value from domain controller name * * #param base a {#link java.lang.String} object - name of the domain controller * #return a {#link java.lang.String} object - base name for eg. DC=myjeeva,DC=com */ private static String getDomainBase(String base) { char[] namePair = base.toUpperCase().toCharArray(); String dn = "DC="; for (int i = 0; i < namePair.length; i++) { if (namePair[i] == '.') { dn += ",DC=" + namePair[++i]; } else { dn += namePair[i]; } } return dn; } } Sample Usage Code /** * The MIT License * * Copyright (c) 2010-2012 www.myjeeva.com * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * */ package com.LdapSearchDaoBean; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import javax.naming.NamingEnumeration; import javax.naming.NamingException; import javax.naming.directory.Attributes; import javax.naming.directory.SearchResult; /** * Sample program how to use ActiveDirectory class in Java * * #filename SampleUsageActiveDirectory.java * #author Jeevanandam Madanagopal * #copyright © 2010-2012 www.myjeeva.com */ public class SampleUsageActiveDirectory { /** * #param args * #throws NamingException */ public static void main(String[] args) throws NamingException, IOException { System.out.println("\n\nQuerying Active Directory Using Java"); System.out.println("------------------------------------"); String domain = ""; String username = ""; String password = ""; String choice = ""; String searchTerm = ""; BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); System.out.println("Provide username & password for connecting AD"); System.out.println("Enter Domain:"); domain = br.readLine(); System.out.println("Enter username:"); username = br.readLine(); System.out.println("Enter password:"); password = br.readLine(); System.out.println("Search by username or email:"); choice = br.readLine(); System.out.println("Enter search term:"); searchTerm = br.readLine(); //Creating instance of ActiveDirectory ActiveDirectory activeDirectory = new ActiveDirectory(username, password, domain); //Searching NamingEnumeration<SearchResult> result = activeDirectory.searchUser(searchTerm, choice, null); if(result.hasMore()) { SearchResult rs= (SearchResult)result.next(); Attributes attrs = rs.getAttributes(); String temp = attrs.get("samaccountname").toString(); System.out.println("Username : " + temp.substring(temp.indexOf(":")+1)); temp = attrs.get("givenname").toString(); System.out.println("Name : " + temp.substring(temp.indexOf(":")+1)); temp = attrs.get("mail").toString(); System.out.println("Email ID : " + temp.substring(temp.indexOf(":")+1)); temp = attrs.get("cn").toString(); System.out.println("Display Name : " + temp.substring(temp.indexOf(":")+1) + "\n\n"); } else { System.out.println("No search result found!"); } //Closing LDAP Connection activeDirectory.closeLdapConnection(); } } I tried to use the above code with following input in console: Querying Active Directory Using Java ------------------------------------ Provide username & password for connecting AD Enter Domain: DC=de,DC=*****,DC=com Enter username: ************** ( i've hidden username) Enter password: ************* (i've hidden password) Search by username or email: username Enter search term: user1 And I get following errors Apr 12, 2013 10:35:17 AM com.LdapSearchDaoBean.ActiveDirectory <init> SEVERE: DC=de,DC=*****,DC=com:389 Exception in thread "main" java.lang.NullPointerException at com.LdapSearchDaoBean.ActiveDirectory.searchUser(ActiveDirectory.java:101) at com.LdapSearchDaoBean.SampleUsageActiveDirectory.main(SampleUsageActiveDirectory.java:75) It will be really great if someone can help me out may be with a little explanation on HowTo and how can I actually use this in AutoComplete in JSF2.0 forms. I'm literally lost over this topic. Thanks in advance.
I got the same problem, which i can not resolve, but I maybe can help you with your problem. When the Application asks for the Domain, it wants the IP/Adress like: "10.10.200.1:389" or "my.activedirectoryurl:389" from your active directory. Besides this, the code does not work properly, because there is a null given in line 75 in SampleUsageActiveDirectory and this will always cause the NullPointer-Exception: NamingEnumeration<SearchResult> result = activeDirectory.searchUser(searchTerm, choice, null);
The error you have is, that you have entered the AD values. For hostname just use the real AD server name like ad.myserver.com or the ip address. Then it should work.
Checksum issue CRC16CCITT
I have the following C-code which I am trying to re-write in java. I would like to see similar outputs in both of them but I am getting different outputs. This is for computation of checksum. Here is the C-code: #include <ctype.h> #include <string.h> #include <stdio.h> /*~+:CRC Table*/ static unsigned short crctab[256] = { 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485, 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4, 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70, 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067, 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C, 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3, 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0 }; void convert_toASCII (char *buffer, int value) { /* Function converts given 'value' into a 4 byte ASCII-HEX-String (with leading zeros) to 'buffer[]' Parameter: char *buffer, int value Returns: none */ static unsigned char hex_num[] = "0123456789ABCDEF"; static unsigned char i; /* HV */ i = (char)((value & 0xf000) >> 12); *buffer = (char)(hex_num[i]); ++buffer; i = (char)((value & 0x0f00) >> 8); *buffer = (char)(hex_num[i]); ++buffer; i = (char)((value & 0x00f0) >> 4); *buffer = (char)(hex_num[i]); ++buffer; i = (char)(value & 0x000f); *buffer = (char)(hex_num[i]); } void calc_crc(unsigned char *databuffer,unsigned int length) { /*~+:Modulname: calc_crc */ /*~+:Calculate serial CRC (according CCITT ) */ /*~+:The serial CRC16 is calculated for a certain length (int length) */ /*~+:over bytes in buffer (char databuffer[]) */ /*~+: */ /*~+:Input: *databuffer pointer to data string */ /*~+: laenge number of chars to build CRC for */ /*~+:Output: the CRC will be added in ASCII characters ( 4 chars) */ /*~+: at the end of the given string and terminated with '\0' */ /*~+: The buffer must be able to handle these additional */ /*~+: 5 characters */ static unsigned char tmp; static unsigned int crc,zaehler; crc = 0; for (zaehler = 0;zaehler < length ;zaehler ++) { tmp=(unsigned char) (crc>>8) ; crc=(crc<<8) ^ crctab[tmp] ^ *databuffer; databuffer++; } printf("%u", crc); /* convert crc -> ASCII */ /* append to string */ convert_toASCII (databuffer, crc); } void main(void) { static char Data[] = {"abcdefghij"}; static char buffer[64]; strcpy(buffer,Datensatz); printf("Data : %s \n\r",&buffer[0]); calc_crc(buffer,10); printf("CRC : %s \n\r",&buffer[10]); printf("Data mit CRC: %s \n\r",&buffer[0]); } The java code that I have written is: public final class Checksum { public static void main(final String[] args) { final String checksumString = "abcdefghij"; final int checksum = calculateCRC16CCITTChecksum(checksumString); System.out.println("Checksum integer value:" + checksum); System.out.println("Checksum value in Hex:" + Integer.toHexString(checksum)); } /** * #param frame The frame for whose checksum has to be calculated. * #return The calculated checksum. */ private final static int calculateCRC16CCITTChecksum(final String frame) { final int[] CRC16_Lookup = {0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485, 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4, 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70, 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067, 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C, 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3, 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0}; // check sum for polynomial 1.x16 + 0.x15 + 0.x14 + 0.x13 + 1.x12 + 0.x11 + 0.x10 + 0.x9 + 0.x8 + 0.x7 + 0.x6 + 1.x5 + 0.x4 + 0.x3 + 0.x2 +0.x1 + 1.x0. // 1.x16 - implies 1 multiplied by 'x' to the power of 16. int crc = 0; for (int i = 0, size = frame.length(); i < size; i++) { crc = (crc << 8) ^ CRC16_Lookup[(crc >> 8) & 0xFF] ^ (frame.charAt(i) & 0xFF); } return crc & 0xFFFF; } } The integer value output that I get in java code is different from what the decimal value that I get in C, even the hex string conversion in java yields different results to that of hex conversion in C. Please guide me what I am doing wrong. Thanks for looking!!
This is not strictly related to an implementation problem, but I guess it's worth mentioning anyway. Keep in mind that some communication protocols require XORing the input values and output values with some value, not to mention bit or byte reflecting of the input data. This happens in Ethernet, which uses CRC-32 for the actual calculations, but the input and output data is XORed with FF..FF (so, it's NOTed), and all the bits in the input byte (or, more naturally, nibble) are reflected. Keep that in mind - the actual calculations might be alright, but there might be something you're simply not aware of in terms of mangling the data, what leads to completely different results.
By code inspection, one can see that in Java the CRC is limited to 16 bits before being printed in decimal (use of & 0xFFFF before returning the function). In C, the value printed is the full unsigned int, so applying the same mask should do the trick. I can't understand why the hex values differ, though...