Pergunta

Quero enviar uma mensagem_original entre duas pessoas.Diga Alice e Bob, e eu quero saber se essas etapas estão corretas para a verificação da assinatura ou não

  1. Alice faz o hash da mensagem_original com sua PrivateKey -> h(m)
  2. Alice cifra a mensagem hash -> c(h(m))
  3. Alice assina a mensagem com sua PrivateKey -> s(c(h(m)))

Alice envia a mensagem final assinada com ela (PublicKey) e (a mensagem_original) para Bob.no lado de Bob:

  1. Bob faz hash da mensagem_original -> h(m)
  2. Bob decifra a mensagem assinada com a chave pública de Alice -> d(s(c(h(m))))
  3. Bob verifica a mensagem decifrada com a mensagem hash se são iguais ou não?se (h(m) == d(s(c(h(m)))))

Eu sei que estou cometendo algum erro.alguém sabe qual é a boa ordem em ambos os lados?

Aqui eu usei java.security para fazer isso, mas quando verifico os hashes na etapa final, recebo false !

na parte Alice:

public byte[] Sign(byte[] aMessage) {

        try {
            // get an instance of a cipher with RSA with ENCRYPT_MODE
            // Init the signature with the private key
            // Compute signature
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, thePrivateKey);

            Signature instance = Signature.getInstance("MD5withRSA");
            instance.initSign(thePrivateKey);

            // get an instance of the java.security.MessageDigest with MD5
            // process the digest
            MessageDigest md5_digest = MessageDigest.getInstance("MD5");
            md5_digest.update(aMessage);
            byte[] digest = md5_digest.digest();

            // return the encrypted digest
            byte[] cipherText = cipher.doFinal(digest);

            instance.update(cipherText);            
            byte[] signedMSG = instance.sign();

            return signedMSG;

        } catch (Exception e) {
            System.out.println("Signature error");
            e.printStackTrace();
            return null;
        }

    }

na parte de Bob:

public boolean CheckSignature(byte[] aMessage, byte[] aSignature,
            PublicKey aPK) {
        try {
            // get an instance of a cipher with RSA with ENCRYPT_MODE
            // Init the signature with the private key
            // decrypt the signature
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, aPK);
            byte[] decrypted_digest =  cipher.doFinal(aSignature);

            // get an instance of the java.security.MessageDigest with MD5
            MessageDigest md5_digest = MessageDigest.getInstance("MD5");

            // process the digest
            md5_digest.update(aMessage);
            byte[] digest = md5_digest.digest();

            // check if digest1 == digest2
            if (decrypted_digest == digest) {
                return true;
            }else {
                return false;
            }

        } catch (Exception e) {
            System.out.println("Verify signature error");
            e.printStackTrace();
            return false;
        }
    }
Foi útil?

Solução

Finalmente encontrei a resposta.O erro foi fazer um sign() na parte Alice.Porque quando você está fazendo o hash e a criptografia ela já virou uma assinatura, e quando você sign() isso outra vez na parte do Bob ficou impossível recuperar a assinatura com hash.

meu código também é um bom exemplo de "Hashing unidirecional na criptografia de chave pública de segurança java"

esta é a modificação na parte de Alice e tudo funciona depois.

public byte[] Sign(byte[] aMessage) {

        try {
            // get an instance of a cipher with RSA with ENCRYPT_MODE
            // Init the signature with the private key
            // Compute signature
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, thePrivateKey);

            // get an instance of the java.security.MessageDigest with MD5
            // process the digest
            MessageDigest md5_digest = MessageDigest.getInstance("MD5");
            byte[] digest = md5_digest.digest(aMessage);

            // return the encrypted digest
            byte[] cipherText = cipher.doFinal(digest);

            return cipherText;

        } catch (Exception e) {
            System.out.println("Signature error");
            e.printStackTrace();
            return null;
        }

    }

Outras dicas

Assinatura Digital é a cifra criptografada (com chave privada) do Hash da mensagem.

Assinatura s = c(h(m))

Agora s está anexado à mensagem m.A mensagem assinada a ser transmitida de Alice para Bob é m+s

Após receber m+s do lado de Bob, Bob descriptografaria a assinatura com a chave pública de Alice que estaria presente no certificado.Então aqui ele faz d(s) = d(c(h(m)) = h(m)

Além disso, o Bob recebeu a mensagem para calcular o hash da mensagem m que é h(m)

Agora ele compararia os resultados de ambas as etapas acima para ver se eles correspondem.Isso garante que a mensagem não foi adulterada por ninguém.

Esta é a ideia geral de como funcionam as assinaturas digitais.Espero que isto ajude.

A Wikipedia tem uma representação gráfica do mesmo processo aqui:http://upload.wikimedia.org/wikipedia/commons/2/2b/Digital_Signature_diagram.svg

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top