1

そこで、Javaを使用してFacebookのsigned_requestの検証に取り組んでいます。残念ながら、検証プロセスで問題が発生し続けています。私はこのドキュメントを見て、それらのアルゴリズムをエミュレートしましたが、成功しませんでした。私もこのチュートリアルに従い、Facebookが送信したものとは異なる計算された署名を考え出し続けました。

または、少なくとも、String.equals()が私に言っていたのはそれでした。

それで、私はそれをもう少し突くことに決めました。

計算された署名と提供された署名のバイトを反復処理するように設定しました。低くて、見よ、私の署名の最初の32バイトは彼らのものと正確に一致した。さらに400バイト以上のデータが欠落していました。

その時点で、私はおそらく一体何が起こっているのかについてより良い概念を得る必要があると判断しました。SHA-256を調べたところ、実際には32バイトの情報しか作成されていないことがわかりました。そのため、FacebookがHMACSHA-256アルゴリズムを使用して生成されたと主張する400バイトを超えるデータが残っています。SHA-256の最大長をハッシュしているデータの長さと比較する必要があると思いましたが、それは、余裕があることを示しています(メッセージサイズ:575バイト;最大サイズ:2.305843009213694 x 10 ^ 18バイト)。

Facebookはたわごとを作っていますか?それとも私は何かが足りないのですか?

編集

これは、データをハッシュするために使用する関数です。Facebookのシークレットコード(キー用)とbase64urlでエンコードされたJSONオブジェクト(データ用)を渡します。Facebookが提供する署名の最初の32バイトと一致するデータを含む長さ32のバイト配列を一貫して返します。

private byte[] hmacSHA256(String data, String key) throws Exception {
    SecretKeySpec secretKey = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");
    Mac mac = Mac.getInstance("HmacSHA256");
    mac.init(secretKey);
    mac.update(data.getBytes("UTF-8"));
    byte[] hmacData = mac.doFinal();
    return hmacData;
}
4

2 に答える 2

6

私も同様の問題に対する答えを探してここに来たので。これは私のために働くコードです:

import org.apache.commons.codec.binary.Base64;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

private JSONObject parseFBSignedRequest(String signedRequest, String secret) throws UnsupportedEncodingException, Exception {
    //split request into signature and data
    String[] signedRequests = signedRequest.split("\\.", 2);
    //parse signature
    String sig = signedRequests[0];

    //parse data and convert to json object
    String data = signedRequests[1];

    //I assumed it is UTF8
    JSONObject jsonData = new JSONObject(new String(Base64.decodeBase64(data), "UTF-8"));
    //check signature algorithm
    if(!jsonData.getString("algorithm").equals("HMAC-SHA256")) {
        //unknown algorithm is used
        return null;
    }

    //check if data is signed correctly
    if(!hmacSHA256(signedRequests[1], secret).equals(sig)) {
        //signature is not correct, possibly the data was tampered with
        return null;
    }
    return jsonData;
}

//HmacSHA256 implementation 
private String hmacSHA256(String data, String key) throws Exception {
    SecretKeySpec secretKey = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");
    Mac mac = Mac.getInstance("HmacSHA256");
    mac.init(secretKey);
    byte[] hmacData = mac.doFinal(data.getBytes("UTF-8"));
    return new String(Base64.encodeBase64URLSafe(hmacData), "UTF-8");
}
于 2013-01-14T16:44:49.637 に答える
0
于 2012-06-03T21:40:56.843 に答える