packagecom.bookingbug;importjava.io.BufferedReader;importjava.io.ByteArrayInputStream;importjava.io.ByteArrayOutputStream;importjava.io.InputStream;importjava.io.InputStreamReader;importjava.io.OutputStream;importjava.security.InvalidAlgorithmParameterException;importjava.security.InvalidKeyException;importjava.security.NoSuchAlgorithmException;importjava.net.HttpURLConnection;importjava.net.URL;importjava.util.Date;importjava.text.SimpleDateFormat;importjavax.crypto.Cipher;importjavax.crypto.CipherOutputStream;importjavax.crypto.NoSuchPaddingException;importjavax.crypto.spec.IvParameterSpec;importjavax.crypto.spec.SecretKeySpec;importorg.apache.commons.codec.net.URLCodec;importorg.apache.commons.codec.binary.Base64;importorg.apache.commons.codec.digest.DigestUtils;importorg.apache.commons.lang3.time.DateUtils;importorg.json.simple.JSONObject;/**
* Singleton class for creating a BookingBug SSO Token. See {@link #main(String[])} for usage example.
* Requires commons-codec library {@link http://commons.apache.org/codec/}.
*/publicclassTokenGenerator{privatestaticfinalStringCOMPANY_ID="{Your Company ID or Affiliate ID}";privatestaticfinalStringSECURE_KEY="{Your Secure Key}";privatestaticfinalbyte[]INIT_VECTOR="OpenSSL for Ruby".getBytes();privateSecretKeySpecsecretKeySpec;privateIvParameterSpecivSpec;privateURLCodecurlCodec=newURLCodec("ASCII");privateBase64base64=newBase64();privatestaticTokenGeneratorINSTANCE=newTokenGenerator();publicstaticTokenGeneratorgetInstance(){if(INSTANCE==null){INSTANCE=newTokenGenerator();}returnINSTANCE;}privateTokenGenerator(){Stringsalted=SECURE_KEY+COMPANY_ID;byte[]hash=DigestUtils.sha(salted);byte[]saltedHash=newbyte[16];System.arraycopy(hash,0,saltedHash,0,16);secretKeySpec=newSecretKeySpec(saltedHash,"AES");ivSpec=newIvParameterSpec(INIT_VECTOR);}privatevoidencrypt(InputStreamin,OutputStreamout)throwsException{try{byte[]buf=newbyte[1024];Ciphercipher=Cipher.getInstance("AES/CBC/PKCS5Padding");cipher.init(Cipher.ENCRYPT_MODE,secretKeySpec,ivSpec);out=newCipherOutputStream(out,cipher);intnumRead=0;while((numRead=in.read(buf))>=0){out.write(buf,0,numRead);}out.close();}catch(InvalidKeyExceptione){e.printStackTrace();}catch(NoSuchAlgorithmExceptione){e.printStackTrace();}catch(NoSuchPaddingExceptione){e.printStackTrace();}catch(InvalidAlgorithmParameterExceptione){e.printStackTrace();}catch(java.io.IOExceptione){e.printStackTrace();}}publicStringcreate(JSONObjectjson)throwsException{Dateexpires=DateUtils.addHours(newDate(),1);json.put("expires",newSimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(expires));byte[]data=json.toString().getBytes();ByteArrayOutputStreamout=newByteArrayOutputStream();for(inti=0;i<16;i++){data[i]^=INIT_VECTOR[i];}encrypt(newByteArrayInputStream(data),out);Stringtoken=newString(urlCodec.encode(base64.encode(out.toByteArray())));returntoken;}publicstaticvoidmain(String[]args){try{JSONObjectjsonObj=newJSONObject();jsonObj.put("first_name","John");jsonObj.put("last_name","Smith");jsonObj.put("email","smith@example.com");jsonObj.put("mobile","0123456789");jsonObj.put("reference","external-reference");System.out.println(TokenGenerator.getInstance().create(jsonObj));}catch(Exceptione){e.printStackTrace();}}}