2017-12-10 5 views
-1

私はBase64でエンコードされた文字列からハッシュ値を生成する次のコードをC#に用意しています。Java Base64とHmacSHA256の暗号化へのC#

var hmacSha256 = new System.Security.Cryptography.HMACSHA256 { Key = Convert.FromBase64String(key) }; 

string verb = "post"; 
string resourceType = "docs"; 
string resourceId = "dbs/ToDoList/colls/Items"; 
string date = DateTime.UtcNow.ToString("R"); 

string payLoad = string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}\n{1}\n{2}\n{3}\n{4}\n", 
     verb.ToLowerInvariant(), 
     resourceType.ToLowerInvariant(), 
     resourceId, 
     date.ToLowerInvariant(), 
     "" 
); 

byte[] hashPayLoad = hmacSha256.ComputeHash(System.Text.Encoding.UTF8.GetBytes(payLoad)); 
string signature = Convert.ToBase64String(hashPayLoad); 

string authToken = System.Web.HttpUtility.UrlEncode(String.Format(System.Globalization.CultureInfo.InvariantCulture, "type={0}&ver={1}&sig={2}", 
    keyType, 
    tokenVersion, 
    signature)); 

これは完全に問題なく動作し、AndroidアプリのJavaコードに変換したかったのです。私はこれらのsources-

C# vs Java HmacSHA1 and then base64

c# and java - difference between hmacsha256 hash

からの参照をチェックし、Javaで生成されたauthToken値は、C#と一致しないJavaベース

にコードの下に
String restServiceVersion = "2017-02-22"; 

String verb = "post"; 
String resourceType = "docs"; 
String resourceId = "dbs/ToDoList/colls/Items"; 

String dateString = org.apache.http.impl.cookie.DateUtils.formatDate(new Date(System.currentTimeMillis())); 

String gmtIndex = "GMT"; 
int index = dateString.indexOf(gmtIndex); 

String dateStringFinal = dateString.substring(0, index + 3).toLowerCase(); 

String payLoad = verb +"\n" + resourceType + "\n" + resourceId + "\n" + dateStringFinal + "\n\n"; 

System.out.println(payLoad); 

String secretAccessKey = MASTER_KEY; 
String data = payLoad; 
byte[] secretKey = Base64.decode(secretAccessKey, Base64.DEFAULT); 
SecretKeySpec signingKey = new SecretKeySpec(secretKey, "HmacSHA256"); 
Mac mac = Mac.getInstance("HmacSHA256"); 
mac.init(signingKey); 
byte[] bytes = data.getBytes("UTF-8"); 
byte[] rawHmac = mac.doFinal(bytes); 

String authToken = "type=master&ver=1.0&sig=" + Base64.encodeToString(rawHmac, Base64.DEFAULT); 

を書きました。また、Base64デコードから生成されるバイト配列も異なります。

これが正しいアプローチであるかどうかはわかりません。誰かが見てみることができますか?私が必要とするのは、上記のC#コードをAndroidアプリ用のJavaに変換することだけです。

+0

したがって、値が一致しません。どのように非常に有益な..... ** NOT ** – Andreas

+0

ベース64のデコード後のキーのバイトが異なる場合、sha256ハッシュも間違いなく違います。ソースbase64でエンコードされたキーが両方で同じであることを絶対に100%確信していますか?あなたは、各プラットフォームの下でどのような出力を得ているのか、特定の入力について私たちに見せてもらえますか? (使用している正確なキーがローカルテストの目的にのみ使用されている場合は、それを使用できます)。 –

+0

@DylanNicholsonはいソースキーと他のパラメータは同じです。ちょうど私がそれらを適切に構築したかどうか心配しました。 –

答えて

0

ほとんどの場合、あなたのBASE64文字列に埋め込まれた目に見えないユニコード文字(「ゼロ幅の非結合子」など)があります。 1つのプラットフォームはベース64のデコード時にこれらを取り除き、別のプラットフォームは異なるキーになります。

+0

彼が提供したすべての情報(コメントスレッドの上に読まれたもの)を考えれば、これは彼が観察していた行動を説明する唯一の答えです(NBは技術的に「誰かが見てみませんか? –