私は新しいメンバーです。私はアンドロイドクライアントからPythonサーバーへのソリューション検証署名を見つけるのに2日間待っています。 まず、鍵ペアを作成し、秘密鍵から署名を生成します。私は完全なコードを更新しましたpedrofbありがとうございます。 Pythonサーバーで行われたことを確認します。Android/Pythonシグネチャを確認する方法SHA256withRSAとPKCS1パッディング
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
KeyPairGenerator keyPairGenerator = null;
try {
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
//keyStore.deleteEntry("key1");
keyPairGenerator = KeyPairGenerator.getInstance(
KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore");
try {
KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder("key1", KeyProperties.PURPOSE_SIGN)
.setKeySize(2048)
.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
.setDigests(KeyProperties.DIGEST_SHA256)
.setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1);
keyPairGenerator.initialize(builder.build());
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PrivateKey privateKey = (PrivateKey) keyStore.getKey("key1", null);
PublicKey publicKey = keyStore.getCertificate("key1").getPublicKey();
String publicKeyStr = Base64.encodeToString(publicKey.getEncoded(), Base64.NO_WRAP);
Log.d("Hahaha", publicKeyStr);
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(privateKey);
String data = "haha";
signature.update(data.getBytes());
byte[] signatureBytes = signature.sign();
String signatureBase64 = Base64.encodeToString(signatureBytes, Base64.NO_WRAP);
Log.d("Hahaha", signatureBase64);
Signature verifySignature = Signature.getInstance("SHA256withRSA");
verifySignature.initVerify(publicKey);
verifySignature.update(data.getBytes());
boolean isVerify = verifySignature.verify(Base64.decode(signatureBase64, Base64.NO_WRAP));
Log.d("Hahaha", isVerify + "");
} catch (Exception e) {
e.printStackTrace();
}
}
public static String sha256(String rawString){
MessageDigest shaDigest;
byte[] data;
try {
data = rawString.getBytes("UTF-8");
shaDigest = MessageDigest.getInstance("SHA-256");
} catch (Exception e) {
return null;
}
shaDigest.update(data);
return toHex(shaDigest.digest());
}
public static String toHex(byte[] tmp) {
char hexDigits[] =
{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd',
'e', 'f'};
int nBytesLen = tmp.length;
char str[] = new char[nBytesLen * 2];
int k = 0;
for (byte byte0 : tmp) {
str[k++] = hexDigits[byte0 >>> 4 & 0xf];
str[k++] = hexDigits[byte0 & 0xf];
}
return new String(str);
}
やサーバー、私は署名を検証するためにPKCS1_v1_5
を使用し、それはアンドロイドクライアントから
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA256
from Crypto.PublicKey import RSA
from base64 import b64decode
keyDER = b64decode(open('public.der').read())
key = RSA.importKey(keyDER)
message = "haha"
h = SHA256.new(message)
print h.hexdigest()
signature = b64decode(open('signature.der').read())
verifier = PKCS1_v1_5.new(key)
if verifier.verify(h, signature):
print "The signature is authentic."
else:
print "The signature is not authentic."
が送信されます私は、クライアントとサーバーの両方をハッシュ化されたチェックデータを持っている、それは同じだが、falseを返すverifier.verify 、public.der
は変数PublicKeyStr
の値で、signature.der
は可変の値ですSignatureBase64
助けてください。 [コメントで解決]
データがある*ない*同じことが、それは、Javaの「はは」でありますサイドと "ハハ"をPython側に配置します。 –
いくつかのエラーがあります。1)Javaコードと署名と16進数で2回ハッシュしています。 'signature.update(data.getBytes());'と 'verifySignature.update(sha256(data).getBytes());'を使って 'signature.update(sha256(data).getBytes()); '.setBlockModes(KeyProperties.BLOCK_MODE_CBC)'を削除します。3) 'onCreate'が呼び出されるたびにキーペアを作成する必要があります。 – pedrofb
ありがとうございます。 true、verifySignature私はそれがアンドロイドから動作することを確認のみ作成します。私は両方のJava側とPython側に署名するデータは "haha"です。 pythonのh.hexdigest()とsha256(data).getBytes()は同じ値を返します。 – hai