2017-04-06 4 views
1

Je suis en train d'implémenter ma propre version de RSA, avec le schéma de remplissage RSA-OAEP en Java. Ceci est mon code pour l'algorithme de base:Lors du décryptage dans RSA à l'aide de BigIntegers Java, comment conserver un octet nul au début des données d'origine?

public byte[] encrypt(byte[] data, RSA_PublicKey publicKey) { 
    BigInteger message = new BigInteger(data); 
    BigInteger n = publicKey.getModulus(); //RSA Modulus 
    BigInteger e = publicKey.getPublicExponent(); //RSA Public Exponent 
    if (message.compareTo(n) >= 0) { 
     throw new InvalidDataException(); 
    } 
    byte[] cipherText = message.modPow(e, n).toByteArray(); //Encryption 
    return cipherText; 
} 

public byte[] decrypt(byte[] data, RSA_PrivateKey privateKey) { 
    BigInteger cipherText = new BigInteger(data); 
    BigInteger n = privateKey.getModulus(); //RSA Modulus 
    BigInteger d = privateKey.getPrivateExponent(); //RSA Private Exponent 
    if (cipherText.compareTo(n) >= 0) { 
     throw new InvalidDataException(); 
    } 
    if (cipherText.compareTo(n.subtract(BigInteger.ONE)) == 1) { 
     throw new InvalidDataException(); 
    } 
    byte[] message = cipherText.modPow(d, n).toByteArray(); //Decryption 
    return message; 
} 

Dans RSA-OAEP, une série d'opérations sont effectuées sur les données et une graine aléatoire en utilisant une fonction de génération de masque avant le cryptage. Un octet nul est placé devant les données capitonnées. C'est à quoi il ressemble dans mon code:

buffer = ByteBuffer.allocate(k); 
buffer.put((byte)0); 
buffer.put(maskedSeed); 
buffer.put(maskedDB); 
byte[] em = buffer.array(); 
byte[] cipherText = encrypt(em, publicKey); 
return cipherText 

Quand je décrypter cryptogramme, parfois l'octet nul est encore dans le tableau d'octets résultant, et d'autres fois il n'est pas. Par exemple, ces données (en hexadécimal) était la même avant et après le chiffrement déchiffrement:

00c127a743b56f53e46223eba367b63d3378648c1d5ce3e8eec1f714c099a15b674c528d5051c1c9a32dc39fb13ee745864c7f572fa950dc8336a54d89503754f6c18dd463ec1633e6e94638230d9b10cc6e2904f4c69247a8bac0c60885b37b8adefe3b682b3a6d39f445447fa2f173b408346d3d0db086e199ef9c1fd0d14f

Cependant, ces données:

001c924b794c178c9955d4f3211c67ecda59ffe8c4be55c101bcd5ff3ce0a746ca447b5fc8fd8725cbb083e4b9244cf49b6ca84465680c0c49bec2bab3dfab6371673f0d01605d641330592ffb8915229c2dc4ea1ffcdf8a9a0e461fdf224f5cf57f74affac9d35dd3ce61ff1dd068a8c9495290735415984ddb71515823f746

a été déchiffré comme ceci:

1c924b794c178c9955d4f3211c67ecda59ffe8c4be55c101bcd5ff3ce0a746ca447b5fc8fd8725cbb083e4b9244cf49b6ca84465680c0c49bec2bab3dfab6371673f0d01605d641330592ffb8915229c2dc4ea1ffcdf8a9a0e461fdf224f5cf57f74affac9d35dd3ce61ff1dd068a8c9495290735415984ddb71515823f746

Selon la norme RSA, les données rembourré déchiffré est censé être vérifié pour cet octet nul pour assurer qu'il est correctement rembourré et retourner un message d'erreur si ce n'est pas le cas. Je crois que cela a quelque chose à voir avec le fait que BigIntegers est signé. Y at-il une solution de contournement pour ce problème?

+0

* "Quand je décrypter ce cryptogramme, parfois l'octet nul est encore dans le tableau d'octets résultant, et d'autres fois il n'est pas. "* - S'il vous plaît [modifier] votre question pour donner quelques exemples de cela. –

+0

Je viens de réaliser que l'octet zéro n'apparaît pas lorsque le premier bit des données matelassées après l'octet zéro est un 0. Si c'est un 1, cela fonctionne bien. Cela a certainement à voir avec la signature de BigIntegers. – metroidsocrates

+0

C'est ce que vous obtenez pour faire RSA à la main. L'arithmétique de BigInteger n'a aucun concept de la taille de votre réponse. Si le résultat est de 25, vous obtiendrez un octet, quelle que soit la taille du module. Vous devez ajouter des zéros vous-même. Vous pouvez écrire une méthode qui prend un BigInteger et une longueur attendue et retourne un tableau d'octets big-endian de cette longueur avec des zéros ajoutés au besoin. –

Répondre

0

new BigInteger(data) analyse toujours les données en notation à deux-complément où le bit le plus significatif signale le signe. En RSA, tous les chiffres sont positifs, de sorte que vous pouvez définir le signe que 1:

new BigInteger(1, data) 
+0

J'ai essayé ça. Cela ne résout pas le problème. – metroidsocrates

+0

Avez-vous fait cela pour le chiffrement? –

+0

Je l'ai fait pour le cryptage et le décryptage. – metroidsocrates