import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.Security;
import java.util.Calendar;
import java.util.TimeZone;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Hex;
public class DaumOpenApiSign {
private static final Log log = LogFactory.getLog(DaumOpenApiSign.class);
static {
Security.addProvider(new BouncyCastleProvider());
}
public static final int NONCE_BYTE_LENGTH = 8;
static SecureRandom random = null;
static {
try{
random = SecureRandom.getInstance("SHA1PRNG");
byte[] seed = random.generateSeed( 20);
random.setSeed( seed );
log.info( "SecureRandom Generator for OpenAPI Signature is created.");
} catch ( NoSuchAlgorithmException e) {
log.fatal( "Fail to create SecureRandom Generator for OpenAPI Signature.");
}
}
static final String HMAC_SHA1_ALGORITHM_NAME = "hmacsha1";
private static void appendZeroString( StringBuffer buffer, int value) {
if ( value < 10 ) {
buffer.append( '0');
}
buffer.append( value );
}
public static String generateTimeStamp() {
Calendar rightNow = Calendar.getInstance(TimeZone.getTimeZone("GMT+00:00"));
StringBuffer timeStamp = new StringBuffer( 14 );
timeStamp.append( rightNow.get(Calendar.YEAR));
appendZeroString( timeStamp, rightNow.get(Calendar.MONTH) + 1);
appendZeroString( timeStamp, rightNow.get(Calendar.DATE));
appendZeroString( timeStamp, rightNow.get(Calendar.HOUR_OF_DAY));
appendZeroString( timeStamp, rightNow.get(Calendar.MINUTE));
appendZeroString( timeStamp, rightNow.get(Calendar.SECOND));
return timeStamp.toString();
}
public static String generateNonce() {
byte[] nonce = new byte[NONCE_BYTE_LENGTH];
random.nextBytes( nonce );
return new String( Hex.encode(nonce));
}
private static String __sign ( String alg, String key, String toBeSigned ) {
String signature = null;
if ( alg.equals(HMAC_SHA1_ALGORITHM_NAME)) {
try {
Mac mac = Mac.getInstance("HMACSHA1","BC");
byte[] mac_result;
Key mac_key = new SecretKeySpec(Hex.decode(key), "HMACSHA1"); // Convert to key object.
mac.init(mac_key); // Initialize.
mac_result = mac.doFinal( toBeSigned.getBytes("UTF-8"));
signature = new String( Hex.encode( mac_result ) );
} catch ( Exception e) {
e.printStackTrace();
}
}
return signature;
}
public static String sign ( String api_call_url, String alg, String key ) throws SignErrorException {
String auth_param_ts = generateTimeStamp();
String auth_param_nonce = generateNonce();
String auth_param_sig_alg = alg;
StringBuffer toBeSignedBuffer = new StringBuffer(512);
toBeSignedBuffer.append( api_call_url );
toBeSignedBuffer.append( "&ts=" );
toBeSignedBuffer.append( auth_param_ts );
toBeSignedBuffer.append( "&nonce=" );
toBeSignedBuffer.append( auth_param_nonce );
String signature = __sign ( auth_param_sig_alg, key, toBeSignedBuffer.toString() );
toBeSignedBuffer.append( "&sigalg=" );
toBeSignedBuffer.append( auth_param_sig_alg );
toBeSignedBuffer.append( "&sig=" );
toBeSignedBuffer.append( signature );
return toBeSignedBuffer.toString();
}
public static void main(String[] args) {
String api_url = "http://apis.daum.net/search/dsa?apikey=4125603e35da5d8820b07dc7b19050dbc838336b&q=worldcup&results=10&start=1&output=rss";
String signature_key = "8e4d0a924c60e65ccc38b7f9958f37ff5105f8e1";
try {
String signed_api_url = DaumOpenApiSign.sign( api_url, "hmacsha1", signature_key);
System.out.println( "api url : [" + api_url + "]" );
System.out.println( "signed api url : [" + signed_api_url + "]" );
} catch ( Exception e) {
e.printStackTrace();
}
}
}
api url : [http://apis.daum.net/search/dsa?apikey=4125603e35da5d8820b07dc7b19050dbc838336b&q=worldcup&results=10&start=1&output=rss]
signed api url : [http://apis.daum.net/search/dsa?apikey=4125603e35da5d8820b07dc7b19050dbc838336b&q=worldcup&results=10&start=1&output=rss&ts=20060911095728&nonce=af414a6a14b32837&sigalg=hmacsha1&sig=2484ed77cc3bafb93b74c77697c53d1f6cff1424]