2017-12-11 12 views
1

私は新しいメンバーです。私はアンドロイドクライアントから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 助けてください。 [コメントで解決]

+0

データがある*ない*同じことが、それは、Javaの「はは」でありますサイドと "ハハ"をPython側に配置します。 –

+0

いくつかのエラーがあります。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

+0

ありがとうございます。 true、verifySignature私はそれがアンドロイドから動作することを確認のみ作成します。私は両方のJava側とPython側に署名するデータは "haha"です。 pythonのh.hexdigest()とsha256(data).getBytes()は同じ値を返します。 – hai

答えて

0

あなたはJavaコードでJavaコード

1)におけるいくつかのエラーを持っている、あなたはSHA256で二回メッセージを消化し、進値ではなく、バイナリメッセージに署名しています。

SHA256withRSAは、いくつかの操作を実行し、最初にSHA256ダイジェストアルゴリズムをメッセージに適用し、RSA PKCS#1 v1.5アルゴリズムを適用します。 Pythonで(または他の言語で)それは

signature.update(data.getBytes()); 
verifySignature.update(data.getBytes()); 

2と2つの段階

変更

signature.update(sha256(data).getBytes()); 
verifySignature.update(sha256(data).getBytes()); 

でプログラム行うことができます).setBlockModes(KeyProperties.BLOCK_MODE_CBC)を削除します。これは、暗号化パラメータはありませんあなたは一度鍵ペアを作成する必要があり

3)デジタル署名、と呼ばれているonCreateないたびにappliableある

関連する問題