Javaで Oauth経由のTwitter認証 を取得するアプリの実装を検討しています。最初のステップは リクエストトークンの取得 です。 Pythonの例 はアプリエンジン用です。
コードをテストするために、Pythonを実行し、Javaで出力を確認しています。以下に、Pythonハッシュベースのメッセージ認証コード(HMAC)を生成する例を示します。 :
#!/usr/bin/python
from hashlib import sha1
from hmac import new as hmac
key = "qnscAdgRlkIhAUPY44oiexBKtQbGY0orf7OV1I50"
message = "foo"
print "%s" % hmac(key, message, sha1).digest().encode('base64')[:-1]
出力:
$ ./foo.py
+3h2gpjf4xcynjCGU5lbdMBwGOc=
この例をJavaでどのように複製しますか?
Javaで HMACの例 を見ました:
try {
// Generate a key for the HMAC-MD5 keyed-hashing algorithm; see RFC 2104
// In practice, you would save this key.
KeyGenerator keyGen = KeyGenerator.getInstance("HmacMD5");
SecretKey key = keyGen.generateKey();
// Create a MAC object using HMAC-MD5 and initialize with key
Mac mac = Mac.getInstance(key.getAlgorithm());
mac.init(key);
String str = "This message will be digested";
// Encode the string into bytes using utf-8 and digest it
byte[] utf8 = str.getBytes("UTF8");
byte[] digest = mac.doFinal(utf8);
// If desired, convert the digest into a string
String digestB64 = new Sun.misc.BASE64Encoder().encode(digest);
} catch (InvalidKeyException e) {
} catch (NoSuchAlgorithmException e) {
} catch (UnsupportedEncodingException e) {
}
javax.crypto.Mac を使用しています。ただし、 SecretKey コンストラクターはバイトとアルゴリズムを使用します。
Pythonの例のアルゴリズムは何ですか?アルゴリズムなしでJava秘密鍵を作成するにはどうすればよいですか?
HmacSHA1は必要なアルゴリズム名のようです:
SecretKeySpec keySpec = new SecretKeySpec(
"qnscAdgRlkIhAUPY44oiexBKtQbGY0orf7OV1I50".getBytes(),
"HmacSHA1");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(keySpec);
byte[] result = mac.doFinal("foo".getBytes());
BASE64Encoder encoder = new BASE64Encoder();
System.out.println(encoder.encode(result));
生成するもの:
+3h2gpjf4xcynjCGU5lbdMBwGOc=
ここでは簡単に実装するためにSun.misc.BASE64Encoder
を使用しましたが、おそらくSun JREに依存しないものを使用する必要があります。 Commons Codecのbase64-encoder は、たとえば、より良い選択です。
些細なことですが、hmac(key、message)と同等のものを探している場合、デフォルトでpythonライブラリはMD5アルゴリズムを使用するため、JavaでHmacMD5アルゴリズムを使用する必要があります。
私はこの正確な問題があり、この答えが役立つとわかったのでこれに言及しますが、ダイジェストメソッドがhmac()に渡されてウサギの穴に落ちた部分を逃しました。うまくいけば、この答えが他の人が将来同じことをするのを防ぐでしょう。
例えばin Python REPL
>>> import hmac
>>> hmac.new("keyValueGoesHere", "secretMessageToHash").hexdigest()
'1a7bb3687962c9e26b2d4c2b833b2bf2'
これはJavaメソッドと同等です:
import org.Apache.commons.codec.binary.Hex;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
public class HashingUtility {
public static String HMAC_MD5_encode(String key, String message) throws Exception {
SecretKeySpec keySpec = new SecretKeySpec(
key.getBytes(),
"HmacMD5");
Mac mac = Mac.getInstance("HmacMD5");
mac.init(keySpec);
byte[] rawHmac = mac.doFinal(message.getBytes());
return Hex.encodeHexString(rawHmac);
}
}
私の例では、.hexdigest()と同等のことをしています。