HOTP の Java と Golang の実装 (RFC-4226)
Go で HOTP を実装しようとすると、ユーザーは、生成された OTP を Java の対応物と比較しました。この逸脱は、多くの場合、これらの言語のバイト型の処理方法が異なることに起因します。
Java では、バイト データ型は -128 ~ 127 の範囲で符号化されますが、Go では、符号なしの範囲で符号化されます。この違いは、カウンタ値を表すバイト配列の構築に現れます。
Javaコード:
final byte[] b = ByteBuffer.allocate(8).putLong(counter).array();
Go コード:
bs := make([]byte, 8) binary.BigEndian.PutUint64(bs, counter)
Java ではカウンタ値が負の場合に不一致が発生します。生成されたバイト配列を比較すると、ユーザーは b の最後のバイトの不一致に気づくかもしれません。
この問題を解決するには、256 を加算して負の Java バイト値を調整する必要があります。これにより、負の値が にシフトされます。これは確実に同等のものであり、Go 実装との整合性が確保されています。
Java コード (調整):
for (int i = 0; i < b.length; i++) { if (b[i] < 0) { b[i] += 256; } }
さらに、OTP 結果に使用されるエンコーディングが 2 つの言語間で異なります。 Java は 16 進エンコードを使用しますが、Go はデフォルトで Base64 を使用します。一貫性を実現するには、16 進エンコーディングを使用して結果を出力するように Go コードを変更します。
Go コード (16 進エンコーディング):
return hex.EncodeToString(h.Sum(nil))
これらの調整により、HOTP Go の実装は Java の実装と一致し、指定されたカウンタとキーの値に対して同一の OTP 結果を生成する必要があります。
以上がJava と Go が異なる HOTP 値を生成するのはなぜですか? 不一致を修正するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。