wsattacker.library.xmlencryptionattack.attackengine.pkcs1.BleichenbacherAttackerTest.java Source code

Java tutorial

Introduction

Here is the source code for wsattacker.library.xmlencryptionattack.attackengine.pkcs1.BleichenbacherAttackerTest.java

Source

/**
 * WS-Attacker - A Modular Web Services Penetration Testing Framework Copyright
 * (C) 2013 Dennis Kupser
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 51
 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */
package wsattacker.library.xmlencryptionattack.attackengine.pkcs1;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPublicKey;
import java.util.Random;
import wsattacker.library.xmlencryptionattack.attackengine.attacker.pkcs1.BleichenbacherAttacker;
import javax.crypto.Cipher;
import org.apache.log4j.Logger;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Base64;
import org.junit.After;
import org.junit.AfterClass;
import static org.junit.Assert.assertArrayEquals;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import wsattacker.library.xmlencryptionattack.attackengine.TestPKCS1Oracle;
import wsattacker.library.xmlencryptionattack.attackengine.TestPKCS1PlaintextOracle;
import wsattacker.library.xmlencryptionattack.attackengine.Utility;
import wsattacker.library.xmlencryptionattack.attackengine.oracle.base.request.PKCS1OracleRequest;

/**
 * @author Juraj Somorovsky - juraj.somorovsky@rub.de
 */
public class BleichenbacherAttackerTest {

    Logger LOG = Logger.getLogger(BleichenbacherAttackerTest.class);

    private static final byte[] plainPKCS1024 = new byte[] { (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0xc0,
            (byte) 0xff, (byte) 0xee, (byte) 0xba, (byte) 0xbe, (byte) 0xc0, (byte) 0xff, (byte) 0xee, (byte) 0xba,
            (byte) 0xbe, (byte) 0xc0, (byte) 0xff, (byte) 0xee, (byte) 0xba, (byte) 0xbe, (byte) 0xc0, (byte) 0xff,
            (byte) 0xee, (byte) 0xba, (byte) 0xbe, (byte) 0xc0, (byte) 0xff, (byte) 0xee, (byte) 0xba, (byte) 0xbe,
            (byte) 0xc0, (byte) 0xff, (byte) 0xee, (byte) 0xba, (byte) 0xbe, (byte) 0xc0, (byte) 0xff, (byte) 0xee,
            (byte) 0xba, (byte) 0xbe, (byte) 0xc0, (byte) 0xff, (byte) 0xee, (byte) 0xba, (byte) 0xbe, (byte) 0xc0,
            (byte) 0xff, (byte) 0xee, (byte) 0xba, (byte) 0xbe, (byte) 0xc0, (byte) 0xff, (byte) 0xee, (byte) 0xba,
            (byte) 0xbe, (byte) 0xc0, (byte) 0xff, (byte) 0xee, (byte) 0xba, (byte) 0xbe, (byte) 0xc0, (byte) 0xff,
            (byte) 0xee, (byte) 0xba, (byte) 0xbe, (byte) 0xc0, (byte) 0xff, (byte) 0xee, (byte) 0xba, (byte) 0xbe,
            (byte) 0xc0, (byte) 0xff, (byte) 0xee, (byte) 0xba, (byte) 0xbe, (byte) 0xc0, (byte) 0xff, (byte) 0xee,
            (byte) 0xba, (byte) 0xbe, (byte) 0x00, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x03,
            (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x0a, (byte) 0x0b,
            (byte) 0x0c, (byte) 0x0d, (byte) 0x0e, (byte) 0x0f, (byte) 0x10, (byte) 0x11, (byte) 0x12, (byte) 0x13,
            (byte) 0x14, (byte) 0x15, (byte) 0x16, (byte) 0x17, (byte) 0x18, (byte) 0x19, (byte) 0x1a, (byte) 0x1b,
            (byte) 0x1c, (byte) 0x1d, (byte) 0x1e, (byte) 0x1f, (byte) 0x20, (byte) 0x21, (byte) 0x22, (byte) 0x23,
            (byte) 0x24, (byte) 0x25, (byte) 0x26, (byte) 0x27, (byte) 0x28, (byte) 0x29, (byte) 0x2a, (byte) 0x2b,
            (byte) 0x2c, (byte) 0x2d, (byte) 0x2e };

    public BleichenbacherAttackerTest() {
    }

    @BeforeClass
    public static void setUpClass() {
    }

    @AfterClass
    public static void tearDownClass() {
    }

    @Before
    public void setUp() {
    }

    @After
    public void tearDown() {
    }

    /**
     * Test of attack method, of class BleichenbacherAttacker.
     */
    @Test
    @Ignore
    public void testAttack() throws Exception {

        System.out.println("Bleichenbacher Attack test with a constant message");

        // create an oracle and encrypt the message

        TestPKCS1Oracle oracle = new TestPKCS1Oracle();
        Cipher cipher = Cipher.getInstance("RSA/None/NoPadding", new BouncyCastleProvider());
        cipher.init(Cipher.ENCRYPT_MODE, oracle.getPublicKey());
        byte[] encKey = cipher.doFinal(plainPKCS1024);

        BleichenbacherAttacker instance = new BleichenbacherAttacker(encKey, oracle, true);
        byte[] result = instance.executeAttack();

        LOG.info("The decrypted message was found after " + oracle.getNumberOfQueries() + " queries:\n "
                + Utility.bytesToHex(result));
        oracle.getNumberOfQueries();
        assertArrayEquals("The decrypted message must be equal to the encrypted " + "one", plainPKCS1024, result);

    }

    @Test
    @Ignore
    public void testAttackPerformance() throws Exception {

        System.out.println("Bleichenbacher Attack test with a constant message");

        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
        keyGen.initialize(1024);
        KeyPair keyPair = keyGen.genKeyPair();
        RSAPublicKey pubKey = (RSAPublicKey) keyPair.getPublic();

        TestPKCS1PlaintextOracle oracle = new TestPKCS1PlaintextOracle(pubKey);

        int blockSize = pubKey.getModulus().bitLength() / 8;
        System.out.println(blockSize);
        byte[] dummyKey = new byte[blockSize];
        Random r = new Random();
        r.nextBytes(dummyKey);
        dummyKey[0] = 0;
        dummyKey[1] = 2;

        BleichenbacherPlaintextAttacker instance = new BleichenbacherPlaintextAttacker(dummyKey, oracle);
        byte[] result = instance.executeAttack();

        LOG.info("The decrypted message was found after " + oracle.getNumberOfQueries() + " queries:\n "
                + Utility.bytesToHex(result));

        Cipher cipher = Cipher.getInstance("RSA/None/NoPadding", new BouncyCastleProvider());
        cipher.init(Cipher.ENCRYPT_MODE, oracle.getPublicKey());
        byte[] encKey = cipher.doFinal(dummyKey);

        LOG.info("Encrypted Key in Base64: " + new String(Base64.encode(encKey)));

    }

    private static X509Certificate loadCert(String fileName)
            throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException {
        CertificateFactory factory = CertificateFactory.getInstance("X.509");
        X509Certificate certificate = (X509Certificate) factory.generateCertificate(new FileInputStream(fileName));
        return certificate;
    }
}