RSA Encryption

Dear colleagues,
do you have any idea how to nicely implement RSA encryption in PL/SQL? I couldn't find anything interesting (including DBMS_CRYPTO package).
Many thanks in advance

And maybe: Cryptography

Similar Messages

  • Cannot decrypt RSA encrypted text : due to : input too large for RSA cipher

    Hi,
    I am in a fix trying to decrypt this RSA encrypted String ... plzz help
    I have the encrypted text as a String.
    This is what I do to decrypt it using the Private key
    - Determine the block size of the Cipher object
    - Get the array of bytes from the String
    - Find out how many block sized partitions I have in the array
    - Encrypt the exact block sized partitions using update() method
    - Ok, now its easy to find out how many bytes remain (using % operator)
    - If the remaining bytes is 0 then simply call the 'doFinal()'
    i.e. the one which returns an array of bytes and takes no args
    - If the remaining bytes is not zero then call the
    'doFinal(byte [] input, int offset, in inputLen)' method for the
    bytes which actually remained
    However, this doesnt work. This is making me go really crazy.
    Can anyone point out whats wrong ? Plzz
    Here is the (childish) code
    Cipher rsaDecipher = null;
    //The initialization stuff for rsaDecipher
    //The rsaDecipher Cipher is using 256 bit keys
    //I havent specified anything regarding padding
    //And, I am using BouncyCastle
    String encryptedString;
    // read in the string from the network
    // this string is encrypted using an RSA public key generated earlier
    // I have to decrypt this string using the corresponding Private key
    byte [] input = encryptedString.getBytes();
    int blockSize = rsaDecipher.getBlockSize();
    int outputSize = rsaDecipher.getOutputSize(blockSize);
    byte [] output = new byte[outputSize];
    int numBlockSizedPartitions = input.length / blockSize;
    int numRemainingBytes = input.length % blockSize;
    boolean hasRemainingBytes = false;
    if (numRemainingBytes > 0)
      hasRemainingBytes = true;
    int offset = 0;
    int inputLen = blockSize;
    StringBuffer buf = new StringBuffer();
    for (int i = 0; i < numBlockSizedPartitions; i++) {
      output = rsaDecipher.update(input, offset, blockSize);
      offset += blockSize;
      buf.append(new String(output));
    if (hasRemainingBytes) {
      //This is excatly where I get the "input too large for RSA cipher"
      //Which is suffixed with ArrayIndexOutofBounds
      output = rsaDecipher.doFinal(input,offset,numRemainingBytes);
    } else {
      output = rsaDecipher.doFinal();
    buf.append(new String(output));
    //After having reached till here, will it be wrong if I assumed that I
    //have the properly decrypted string ???

    Hi,
    I am in a fix trying to decrypt this RSA encrypted
    String ... plzz helpYou're already broken at this point.
    Repeat after me: ciphertext CANNOT be safely represented as a String. Strings have internal structure - if you hand ciphertext to the new String(byte[]) constructor, it will eat your ciphertext and leave you with garbage. Said garbage will fail to decrypt in a variety of puzzling fashions.
    If you want to transmit ciphertext as a String, you need to use something like Base64 to encode the raw bytes. Then, on the receiving side, you must Base64-DEcode back into bytes, and then decrypt the resulting byte[].
    Second - using RSA as a general-purpose cipher is a bad idea. Don't do that. It's slow (on the order of 100x slower than the slowest symmetric cipher). It has a HUGE block size (governed by the keysize). And it's subject to attack if used as a stream-cipher (IIRC - I can no longer find the reference for that, so take it with a grain of salt...) Standard practice is to use RSA only to encrypt a generated key for some symmetric algorithm (like, say, AES), and use that key as a session-key.
    At any rate - the code you posted is broken before you get to this line:byte [] input = encryptedString.getBytes();Go back to the encrypting and and make it stop treating your ciphertext as a String.
    Grant

  • Can I encrypt a string with RSA encryption using DBMS_CRYPTO?

    We have an web application that does a redirect thru a database package to a 3rd party site. They would like us to encrypt the querystring that is passed using RSA encryption. The example that they've given us (below) uses the RSA cryptographic service available in .NET. Is it possible to do this using DBMS_CRYPTO or some other method in Oracle?
    Below are the steps outlined to use the key to generate the encrypted URL
    2.1 Initialize Service
    The RSA cryptographic service must be initialized with the provided public key. Below is sample code that can be used to initialize the service using the public key
    C#
    private void InitializeRSA( string keyFileName )
    CspParameters cspParams = new CspParameters( );
    cspParams.Flags = CspProviderFlags.UseMachineKeyStore;
    m_sp = new RSACryptoServiceProvider( cspParams );
    //Load the public key from the supplied XML file
    StreamReader reader = new StreamReader( keyFileName );
    string data = reader.ReadToEnd( );
    //Initializes the public key
    m_sp.FromXmlString( data );
    2.2 Encryption method
    Create a method that will encrypt a string using the cryptographic service that was initialized in step 2.1. The encryption method should convert the encryption method to Base64 to avoid special characters from being passed in the URL. Below is sample code that uses the method created in step 2.1 that can be used to encrypt a string.
    C#
    private string RSAEncrypt( string plainText )
    ASCIIEncoding enc = new ASCIIEncoding( );
    int numOfChars = enc.GetByteCount( plainText );
    byte[ ] tempArray = enc.GetBytes( plainText );
    byte[ ] result = m_sp.Encrypt( tempArray, false );
    //Use Base64 encoding since the encrypted string will be used in an URL
    return Convert.ToBase64String( result );
    2.3 Generate URL
    The query string must contain the necessary data elements configured for you school in Step 1. This will always include the Client Number and the Student ID of the student clicking on the link.
    1.     Build the query string with Client Number and Student ID
    C#
    string queryString = “schoolId=1234&studentId=1234”;
    The StudentCenter website will validate that the query string was generated within 3 minutes of the request being received on our server. A time stamp in UTC universal time (to prevent time zone inconsistencies) will need to be attached to the query string.
    2.     Get the current UTC timestamp, and add the timestamp to the query string
    C#
    string dateTime = DateTime.UtcNow.ToString(“yyyy-MM-dd HH:mm:ss”);
    queryString += “&currentDT=” + dateTime;
    Now that the query string has all of the necessary parameters, use the RSAEncrypt (Step 2.2) method created early to encrypt the string. The encrypted string must also be url encoded to escape any special characters.
    3.     Encrypt and Url Encode the query string
    C#
    string rsa = RSAEncrypt(querystring);
    string eqs = Server.UrlEncode(rsa);
    The encrypted query string is now appended to the Url (https://studentcenter.uhcsr.com), and is now ready for navigation.
    4.     Build the URL
    C#
    string url = “https://studentcenter.uhcsr.com/custom.aspx?eqs=” + eqs

    The documentation lists all the encyrption types:
    http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14258/d_crypto.htm#ARPLS664

  • Is it enough only use RSA encryption?

    Hi all,
    I want to know is it enough if we develop Java Card application by using only RSA encryption?..
    if on-card application uses RSA, and so off-card application uses RSA, is it mean that we have to use 2 KeyPairs?..
    I mean, the off-card shall generate Pub and Priv Key, Keep Priv-Key secret, and the Pub key is distributed to card..
    and of course on-card do same thing, it will generate Pub and Priv Key, Keep Priv-Key secret, and the Pub key is distributed to Off-card application..
    Please correct me if this wrong..
    if this isn't wrong, do i still have to use X509Certificate?..
    Thanks in advance,,

    Thanks Lexdabear and Shane for your reply..
    Actually, i'm a little bit confused how do i can make sure the data is being sent is confidential and valid (it means that the data received by receiver is same with the data sent by sender)..
    Hm, i read from the PDF document that i downloaded from the internet, says that :
    &#9679; Signing
    Use private key to “sign” data
    &#9679; Verification
    Use public key to verify “signature”
    &#9679; Encryption
    Use public key to encrypt data
    &#9679; Decryption
    Use private key to decrypt data
    Can i mix these features together if i only use single RSA Key-Pair (only on the card side)?, assume that the on-card application hold only Private-Key, can on-card do these features together ((encrypt, decrypt, sign, verify) if it has only Private Key? ..
    based on that, it means that if we use only single RSA KeyPair, assume that the Card holds the Private Key and the Off-card holds the Public-Key, so the application in the card can only do Sign and Encrypt data before data sent to the off-card, and of course, the off-card can only do Verify signature and Decrypt data received..
    So, how the card can decrypt and verify the signature of the data sent by off-card if the card doesn't hold the public key of the off-card ?
    i thought the off-card SHOULD send its Public-Key to the on-card application, so the On-Card application can do Decrypt and Verify the signature of data sent by Off-Card..
    i thought single RSA keypair isn't enough (My point of view as a less of experience programmer)
    Please correct me if i'm wrong..
    Thanks in advance..
    Edited by: Leonardo_Carreira on Jun 22, 2010 2:22 AM

  • How to encode/pad an RSA-Encrypted Triple-DES Key

    Similar to this guy's problem: http://forum.java.sun.com/thread.jspa?messageID=3332692&#3332692
    I am having an issue along the same lines... I'm writing a java client that is dealing with a C++ agent, which is expecting an encrypted TripleDES key. However when I create a DesEDE key, then encrypt it using a public RSA key, I am only sending 24 bytes, where the C++ code is expecting 32.
    Luckily, I DO have a C++ client that is doing what I need to do, so I'm investigating exactly how they're doing with the padding/encoding in order to fix my problem. But it's using the crypto 5.1 library (crypto++ maybe) and its not the most readable code.
    If anyone's done anything similar, I'd appreciate any tips/advice for how you dealt with it.
    tOm

    32/24 == 4/3 == the expansion ration converting bytes to Base64.
    Is this a possibility?

  • Help with RSA Encryption using SATSA

    Hello,
    I am a new to writing code on J2ME . I am trying to encrypt data using
    RSA public key on J2ME using SATSA.
    I generated the public key using openssl in the PEM format and stored the
    key (mypublickey) as a Base64 decoded byte array in my code.
    Next, I did the following:
    X509EncodedKeySpec test - new X509EncodedKeySpec(mypublickey);
    KeyFactory kf = KeyFactory.getInstance("RSA");
    PublicKey key = kf.generatePublic(test);
    I used this key to encrypt as follows:
    cipher c = Cipher.getInstance("RSA");
    c.init(Cipher.ENCRYPT_MODE, key);
    c.doFinal(data,0,data.length,ciphertext,0);
    where byte[] data = "1234567890".getBytes();
    I get no errors during this process.
    Now, when I try to decrypt the string, I get a padding error as follows:
    javax.crypto.BadPaddingException: Data must start with zero
    The decode is done on a server.
    I tried getting an instance of the cipher with RSA/ECB/NoPadding and this time the decrypt gives junk.
    Question 2: The SATSA example online at http://java.sun.com/j2me/docs/satsa-dg/AppD.html
    has a public key embedded as a byte array. They haven't explained how
    this key is generated. Does someone know?
    Question 3: Suppose, I can get the modulus and exponent of the public key is there any way I can convert it to X509EncodedKeySpec so that I can
    use the APIs in SATSA?
    Thanks in advance for your help. I have been trying to solve this for a lot of time and any help will be greatly appreciated.

    Just wanted to add my code:
    public class test2 {
         public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, ShortBufferException {
              // TODO Auto-generated method stub
              byte [] data = "012345678901234567890123456789ab".getBytes();
              Base64 base64 = new Base64();
    /*public key generated by
              byte [] mypublickey = base64.decode("publickey in PEM format");
              byte [] ciphertext = new byte[128];
              X509EncodedKeySpec test = new X509EncodedKeySpec(mypublickey);
              byte [] myprivatekey = base64.decode("privatekey in pkcs8format");
    KeyFactory rsakeyfac = KeyFactory.getInstance("RSA");
              PublicKey pubkey = rsakeyfac.generatePublic(test);
              Cipher c1 = Cipher.getInstance("RSA");
              c1.init(Cipher.ENCRYPT_MODE, pubkey);
              c1.doFinal(data, 0,data.length, ciphertext);
              PKCS8EncodedKeySpec pks2 = new PKCS8EncodedKeySpec(myprivatekey);
              RSAPrivateCrtKey privkey = (RSAPrivateCrtKey)rsakeyfac.generatePrivate(pks2);
              Cipher c2 = Cipher.getInstance("RSA");
              c2.init(Cipher.DECRYPT_MODE, privkey);
              byte [] decrypteddata = c2.doFinal(ciphertext);
              System.out.println("Decrypted String is:"+new String(decrypteddata).trim());
    Error that I get is:
    Exception in thread "main" javax.crypto.BadPaddingException: Data must start with zero
         at sun.security.rsa.RSAPadding.unpadV15(Unknown Source)
         at sun.security.rsa.RSAPadding.unpad(Unknown Source)
         at com.sun.crypto.provider.RSACipher.a(DashoA13*..)
         at com.sun.crypto.provider.RSACipher.engineDoFinal(DashoA13*..)
         at javax.crypto.Cipher.doFinal(DashoA13*..)

  • Java card Applet RSA encryption Problems with Android

    hi all,I am new to java card development. I have used nxp jcop 31-36 java card and nexus s for testing the application.so i have faced lot of problems.first of all i want to encrypt data coming from the android app using RSA1024 and send back to the android application.there are the problems I faced
    1.RSA1024 and RSA2048 algorithms can't work with the nexus s Application.it means i can't receive any encrypt data from card.but when i test the application with eclipse jcop shell tool it is work properly.
    2.when i run the application in nexus s the application is crashed.it gives some wired sound when tap the java card to android phone.it may be java card application crashed or give some wired sound from android OS level.
    3.Then I Test the Application with Samsung S2. Sometimes it works but sometimes it crashed.in the S2 the encryption works fine(but we have to keep wile card 2 or 3 minutes).
    these are the steps i followed in established the connection i android phone.So fist i created the ISO dep connection and first select the Application(00A40400AID).Then using transive method i send data to java card.In the Java card in the installation i have created the RSA key pairs and get the RSA public key and private key.in some method i got the APDU buffer and read data and encrypt this data.Then those are send back to the card. First i want to know is there any problem in Android Os or JCOP 31/36 card.And other thing each time i requested to java crd is that need to reset the java card and how to reset the Java card.(some brief idea)

    Hi,
    1) Import android.smartcard libraries,
    2) Try to make a connection :
    ISmartcardConnectionListener connectionListener = new ISmartcardConnectionListener()3) create an instance of smartcardclient:
    smartcard = new SmartcardClient(this, connectionListener);4) get the list of readers :
    String[] readers = smartcard.getReaders();you can check if a specific reader is connected or nor with
    smartcard.isCardPresent(readers [0]);5) create a card channel and select your applet:
    cardChannel = smartcard.openLogicalChannel(cardReader, APPLET_AID);
    ICardChannel cardChannel = null;
    cardChannel = smartcard.openLogicalChannel(cardReader, APPLET_AID);6) you can send and receive APDUs with this line of code:
    byte[] response Apdu = cardChannel.transmit(commandApdu);Regards,
    Hana

  • RSA with Cryptix: can encrypt but not decrypt? Please help.. :)

    Hi all,
    I've been trying to do RSA encryption/decryption using a pair of keys created with keytool. I've been able to encrypt some bytes, but when I attempt to decrypt the results immediately using the private key, I received the following exception:
    IllegalBlockSizeException: RSA: Cipher in DECRYPT state with an incomplete final block
    Please can anyone save me out of my misery and shed some light on this problem? Thanks a great deal in advance.
    Best Regards,
    Kenshin
    Here are the code snippets:
    // 1. imported APIs:
    import javax.net.ssl.*;
    import java.io.*;
    import java.security.*;
    import java.security.interfaces.*;
    import java.security.spec.*;
    import java.security.cert.*;
    import java.security.cert.Certificate;
    import javax.crypto.*;
    import javax.crypto.spec.*;
    import cryptix.provider.Cryptix;
    import xjava.security.Cipher;
    import xjava.security.CipherInputStream;
    import xjava.security.CipherOutputStream;
    import xjava.security.interfaces.*;
    import cryptix.provider.rsa.*;
    // 2. Getting the Public Key from the created cert:
    File certFile = new File("c:/keystore/jbossSSL.cer");
    FileInputStream certFileInStream = new FileInputStream(certFile);
    CertificateFactory cf = CertificateFactory.getInstance("X509");
    Certificate cert = (Certificate)cf.generateCertificate(certFileInStream);
    RSAPublicKey serverPublicKey = (RSAPublicKey)cert.getPublicKey();
    // 3. Doing the encryption:
    Security.addProvider( new cryptix.provider.Cryptix());
    Cipher cipherInstance = Cipher.getInstance("RSA/ECB/PKCS7", "Cryptix");
    CryptixRSAPublicKey vCryptixRSAPubKey = (CryptixRSAPublicKey) new RawRSAPublicKey(serverPublicKey.getPublicExponent());
    cipherInstance.initEncrypt(vCryptixRSAPubKey);
    System.out.println("String to be encypted: " + sRandomString);
    // Sample of what is printed: String to be encypted: 2201162506010696613
    ByteArrayInputStream clearTextInStream = new ByteArrayInputStream(sRandomString.getBytes());
    CipherInputStream cInStream = new CipherInputStream(clearTextInStream, cipherInstance);
    ByteArrayOutputStream cipherTextOutStream = new ByteArrayOutputStream();
    CipherOutputStream cOutStream = new CipherOutputStream(cipherTextOutStream, cipherInstance);
    byte[] buffer = new byte[8192];
    int length;
    while((length= cInStream.read(buffer))!=-1)
    cOutStream.write(buffer, 0, length);
    cOutStream.close();
    cInStream.close();
    cipherTextOutStream.close();
    clearTextInStream.close();
    String sEncodedString = new String(cipherTextOutStream.toByteArray());
    System.out.println("String encrpted: " + sEncodedString);
    // Sample of what is printed: String to encrpted: 2 2 01 1 6 25 0 6 01 0 6 96 6 1 3&#9786; &#9787;&#9787;
    // 4. Getting the Private key from the keystore
    FileInputStream in = new FileInputStream("C:/keystore/jbossSSL.keystore");
    KeyStore catalinaKeyStore = KeyStore.getInstance("jks");
    catalinaKeyStore.load(in, "jbossSSL".toCharArray());
    RSAPrivateKey privateK = (RSAPrivateKey)catalinaKeyStore.getKey("jbossSSL", "jbossSSL".toCharArray());
    CryptixRSAPrivateKey vCryptixRSAPriKey = (CryptixRSAPrivateKey) new RawRSAPrivateKey(privateK.getPrivateExponent(), privateK.getModulus());
    cipherInstance.initDecrypt(vCryptixRSAPriKey);
    // 5. Doing the decryption:
    ByteArrayInputStream cipherTextInStream = new ByteArrayInputStream(sEncodedString.getBytes());
    cInStream = new CipherInputStream(cipherTextInStream,cipherInstance);
    ByteArrayOutputStream clearTextOutStream = new ByteArrayOutputStream();
    cOutStream = new CipherOutputStream(clearTextOutStream,cipherInstance);
    while((length= cInStream.read(buffer))!=-1)
    cOutStream.write(buffer, 0, length); >> exception thrown here
    cOutStream.close();
    cInStream.close();
    clearTextOutStream.close();
    cipherTextInStream.close();
    String sDecodedString = new String(clearTextOutStream.toByteArray());
    System.out.println("Stringdecrpted: " + sDecodedString);

    Here is working RSA example Maybe will help you. (may has a few typing errors becosu I rmoved some confidential data ;) )
    import java.util.*;
    import javax.swing.*;
    import java.io.*;
    import java.security.*;
    import javax.crypto.Cipher;
    import xjava.security.*;
    import cryptix.provider.Cryptix;
    import xjava.security.interfaces.CryptixRSAPublicKey;
    import xjava.security.interfaces.CryptixRSAPrivateKey;
    import xjava.security.KeyGenerator;
    import xjava.security.SecretKey;
    public class testcipher extends javax.swing.JFrame{
        /** Creates new test */
        public testcipher() throws Exception {
        * @param args the command line arguments
        public static void main(String [] args) throws Exception  {
            Provider pd = new cryptix.provider.Cryptix();
            Security.addProvider(pd);
            KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "Cryptix");
            kpg.initialize(1024, new java.security.SecureRandom());
            System.out.println("Generating key pair...");
            KeyPair kp = kpg.genKeyPair();
            System.out.println("Key pair generated...");
            xjava.security.Cipher cp = xjava.security.Cipher.getInstance("RSA/ECB/PKCS7", "Cryptix");
            cp.initEncrypt(kp.getPublic());
            FileInputStream fis = new FileInputStream("c:\\temp\\b2b\\index.htm");
            CipherInputStream cin = new CipherInputStream(fis, cp);
            FileOutputStream fout = new FileOutputStream("C:\\temp\\b2b\\enc.htm");
            CipherOutputStream cout = new CipherOutputStream(fout, cp);
            byte[] buffer = new byte[8192];
            int length;
            while((length=cin.read(buffer))!=-1)
                cout.write(buffer, 0, length);
            cout.close();
            cin.close();
            fout.close();
            fis.close();
            cp.initDecrypt(kp.getPrivate());
            fis = new FileInputStream("c:\\temp\\b2b\\enc.htm");
             cin = new CipherInputStream(fis, cp);
             fout = new FileOutputStream("C:\\temp\\b2b\\dec.htm");
             cout = new CipherOutputStream(fout, cp);
                    while((length=cin.read(buffer))!=-1)
                cout.write(buffer, 0, length);
            cout.close();
            cin.close();
            fout.close();
            fis.close();
    }

  • How to encrypt more than 117 bytes with RSA?

    Hi there,
    I am struggling to encrypt more than 117 bytes of data with a 1024 bit RSA key.
    If I try to encrypt (write to my OutputStreamWriter) 118 Bytes ("A"s) or more, the file I am writing to is just empty and I get an exception whe trying to read it.
    I know the encryptable bytes (blocksize) are related to the key length: blocksize = keylength / 8 -11
    I also know RSA encryption of large files is discouraged, because it is like 100x slower than for instance AES and was originally only intended to exchange symmetric keys.
    Still I need to be able to asymmetrically encrypt at least 5kb of Data.
    I am out of ideas here and have no understanding of why the block size is limited (i know from hours of "googling" that it is limited as described above though).
    So, I would be very glad If somebody could point out a way how I could encrypt more than 117 bytes (without using a longer key of course).
    import java.io.FileInputStream;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.io.FileOutputStream;
    import java.io.Reader;
    import java.io.Writer;
    import java.io.OutputStreamWriter;
    import java.security.PublicKey;
    import java.io.IOException;
    import java.security.InvalidKeyException;
    import java.security.KeyPair;
    import java.security.KeyPairGenerator;
    import java.security.NoSuchAlgorithmException;
    import java.security.PrivateKey;
    import javax.crypto.*;
    public class strchrbty {
         public static void main(String[] args) {
              //generate Keys
              PublicKey publicKey = null;
              PrivateKey privateKey = null;
              try {
                   KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
                   kpg.initialize(1024);
                   KeyPair kp = kpg.generateKeyPair();
                   publicKey = kp.getPublic();
                   privateKey = kp.getPrivate();
              } catch (NoSuchAlgorithmException e) {
                   e.printStackTrace();
              //------ENCODE------
              try {
                  //initialize cipher
                  Cipher cipher = Cipher.getInstance("RSA");  
                   cipher.init(Cipher.ENCRYPT_MODE, publicKey);   
                   OutputStream cos = new CipherOutputStream(new FileOutputStream("c:\\test.txt"), cipher);
                  Writer out = new OutputStreamWriter(cos);
                  // 1024 bit (key length) / 8 bytes - 11 bytes padding = 117 Bytes Data.
                  //  for 118 Bytes (or more) Data: c:\\test.txt is empty annd no Data is read.
                  for(int i = 0; i<117; i++) {
                       out.write("A");
                  out.close();
                  cos.close();
             } catch (InvalidKeyException e) {
                  e.printStackTrace();      
             } catch (NoSuchPaddingException e) {
                  e.printStackTrace();           
             } catch (NoSuchAlgorithmException e) {
                  e.printStackTrace();      
             } catch (IOException e) {
                  e.printStackTrace();
             //------DECODE------
             try {
                  StringBuffer buf = new StringBuffer();
                  Cipher cipher2 = Cipher.getInstance("RSA"); 
                  cipher2.init(Cipher.DECRYPT_MODE, privateKey);
                  //read char-wise
                  InputStream cis = new CipherInputStream(new FileInputStream("c:\\test.txt"), cipher2);
                  Reader in = new InputStreamReader(cis);
                  for(int c = in.read(); c != -1; c = in.read()) {
                    buf.append((char)c);
                  //output
                  System.out.println(buf.toString());
                  in.close();
                  cis.close();
              } catch (InvalidKeyException e) {
                  e.printStackTrace();      
             } catch (NoSuchPaddingException e) {
                  e.printStackTrace();           
             } catch (NoSuchAlgorithmException e) {
                  e.printStackTrace();      
              } catch(IOException e) {
                 e.printStackTrace();
    }Regards.
    Edited by: junghansmega on Sep 10, 2008 3:41 PM
    Sorry about the bad autoformating.... It only occurrs in here, in my eclipse it looks fine =(

    junghansmega wrote:
    Hi there,
    I am struggling to encrypt more than 117 bytes of data with a 1024 bit RSA key.
    If I try to encrypt (write to my OutputStreamWriter) 118 Bytes ("A"s) or more, the file I am writing to is just empty and I get an exception whe trying to read it.
    Good, it should be painful.
    >
    Still I need to be able to asymmetrically encrypt at least 5kb of Data.
    In this forum, 99.999% of the time this kind of claim is due to a lack of understanding of the role of public key cryptography.
    I am out of ideas here and have no understanding of why the block size is limited (i know from hours of "googling" that it is limited as described above though).
    It should not be difficult to break up the input into 117 byte chunks and encrypt each chunk through a newly initted cipher object. Of course you will have to be very careful in properly encoding the output. You might naively think that the output is always 128 bytes, but is that true? Might it be 127 bytes sometimes? Maybe even 126 bytes?

  • Compability problem with Java and Python  RSA algorithm implementation

    I have client server application. Server is writtein in python, client in java. Client receives messages from server encrypted with RSA (http://stuvel.eu/rsa), and I'm unable to decrypt it. It seems that this is RSA algorithm compatibility problem. I'm using algorithm from java.security package, instatinating Cipher object like this: c = Cipher.getInstance("RSA"); . I noticed that this algorithm produces for input blocks of lengtrh <=117 ouput block of length 128. Server I guess uses the most triviall impelentation of RSA ( (1 byte is encrypted to 1 byte) So i want to make my java algorithm compatibile with this one which server uses. How to do that ? Do i have to instatinate Cipher object in different way ? Or use another library ?

    azedor wrote:
    First you said it was no good because it could only handle <= 117 byte inputs, now you say it is no good because it produces a 128-byte output. You're not making sense.First i said that this two RSA implementations are not compatibile, and first reason i noticed firstly is that Python imlementation for input of length N produces cryptogram of the same length. Not true. In general, the RSA encryption of any number of bytes less than the length of the modulus will produce a result of length near that of the modulus. When N is less than the length of the modulus, it is rare that N bytes of cleartext produces N bytes of ciphertext.
    Java implementation for data block of length <=117 produces alwasy 128 bytes of output.Pretty much correct and very much desirable. This is primarily a function of the PKCS1 padding which is used to solve two basic problems. First, as I alluded to in my first response, it is the nature of the algorithm that leading zeros are not preserved and second when the cleartext is very small (a few bytes) the exponentiation does not roll over and it is easy to decrypt the result. Both these problems are addressed by PKCS1 padding.
    >
    >
    After what sabre150 said i think of giving up idea of translating Python code to Java and considering to use another assymetric cryptography algorithms on both sides. Can you recommend me sth what should be compatibile with Python ?This seems to be at odds with your statement in reply #3 "Also have acces only to client code so i have to change sth in java." ! This statement is why I said "I suspect ... you have dug a deep hole".
    In your position I would use the Python bindings for openssl. Once more, Google is your friend.

  • How Can i use the key file Generated by RSACryptoServiceProvider to encrypt with php?

    I need to be able to encrypt data in PHP using a public key generate by .NET(RSACryptoServiceProvider).  I will then decrypt the data later in C# using the private key.
    Code Snippet
    <RSAKeyValue><Modulus>xU5JyaPNDKXI/h/uo5Vk89wZSz3zsB1+c+1IMYIQa+mCmuRCRPuoBI7ODSV2ndP6grfhdrWEzhpZtkI3SThbBh/3t+tfZ2PF8Iyv9ECN07V64nPCiJGhAnfENE+J9UD9Kw5czXHgZcBbpM5N0VfXmLSleaS65DDoNPtoStVy7ss=</Modulus><Exponent>AQAB</Exponent><P>4ScAjVrPZii/6lICAP2yDQiNEmNL74+5AcxNVDI0IombfDPIygrqEWmuDu0pngApQak7XnEnLbaDChILFiHPZQ==</P><Q>4FaYlse+cjrlPD/jk+GsTJeuP7yuQx8ztjVnQWVh6GKQP+uk1dAl6kcZOfLNR6LWwE3CSygt8PthTEw96Zbabw==</Q><DP>XvXtNLE9UjATqYeHEtXtV7Pok/3PVC3A8PIzFzTJaluxeXP51sU9rbRt1hvO9rXIsMnooU+GH7Cfmgq8JEyERQ==</DP><DQ>HXkC/vwq9xLpvuqd2XXSjxV2XQVK16Knxo5pjFvnawJX9S3eMADymj7Q/534firUj9snZXxX3MsJ015I3AFnnQ==</DQ><InverseQ>AM0fVCE3n2FKf2zb3CcDEge1Ko35VvMEL+LXgR87QwO2HScZSuLevGLi2SSAkB1vu8RSNzB028SZReeOZWnq4Q==</InverseQ><D>fI+GKdRNOTTYhQZnw8Im74T+OvArjf2wvUMJlqfD8jyDBYIhDCfL1MTK9KW4Er+moSuxHR5Pb0ZXaKa4/HKlk0aJ1jB2C+jg7zTSuPRNuS16BpVHaJYsQurCwZwElXMum+GxeXK/h3wXWq5HwebjqZr0aLUMZKRcweDPRoVFiRE=</D></RSAKeyValue>
    As you see this code snippet is a xml format private key. at .net platform,which can use encrypt or dencrypt.
    i have try the Extension Crypt RSA ( http://pear.php.net/reference/Crypt_RSA-1.0.0/elementindex_Crypt_RSA.html ) to help me encrypt data by php.but it haven't return a currect result. the data encrypted by php cann't dencrypt by c#.
    does the RSA algorithm provider by Crypt_RSA can give a stand result as c#?
    BTW :i just use the xmlkeystring like this.
    Code Snippet
    <?php
    require_once("Crypt/RSA.php");
    require_once("includes/Utils.class.php");
        $public_key_string = simplexml_load_string("<RSAKeyValue><Modulus>xU5JyaPNDKXI/h/uo5Vk89wZSz3zsB1+c+1IMYIQa+mCmuRCRPuoBI7ODSV2ndP6grfhdrWEzhpZtkI3SThbBh/3t+tfZ2PF8Iyv9ECN07V64nPCiJGhAnfENE+J9UD9Kw5czXHgZcBbpM5N0VfXmLSleaS65DDoNPtoStVy7ss=</Modulus><Exponent>AQAB</Exponent><P>4ScAjVrPZii/6lICAP2yDQiNEmNL74+5AcxNVDI0IombfDPIygrqEWmuDu0pngApQak7XnEnLbaDChILFiHPZQ==</P><Q>4FaYlse+cjrlPD/jk+GsTJeuP7yuQx8ztjVnQWVh6GKQP+uk1dAl6kcZOfLNR6LWwE3CSygt8PthTEw96Zbabw==</Q><DP>XvXtNLE9UjATqYeHEtXtV7Pok/3PVC3A8PIzFzTJaluxeXP51sU9rbRt1hvO9rXIsMnooU+GH7Cfmgq8JEyERQ==</DP><DQ>HXkC/vwq9xLpvuqd2XXSjxV2XQVK16Knxo5pjFvnawJX9S3eMADymj7Q/534firUj9snZXxX3MsJ015I3AFnnQ==</DQ><InverseQ>AM0fVCE3n2FKf2zb3CcDEge1Ko35VvMEL+LXgR87QwO2HScZSuLevGLi2SSAkB1vu8RSNzB028SZReeOZWnq4Q==</InverseQ><D>fI+GKdRNOTTYhQZnw8Im74T+OvArjf2wvUMJlqfD8jyDBYIhDCfL1MTK9KW4Er+moSuxHR5Pb0ZXaKa4/HKlk0aJ1jB2C+jg7zTSuPRNuS16BpVHaJYsQurCwZwElXMum+GxeXK/h3wXWq5HwebjqZr0aLUMZKRcweDPRoVFiRE=</D></RSAKeyValue>");
        $key =new Crypt_RSA_Key(base64_decode($public_key_string->Modulus),base64_decode($public_key_string->Exponent),"public");
        echo "<pre>";
        print_r($key);
        echo "</pre>";
        $rsa_obj = new Crypt_RSA();
        //try encrypt data
        echo "encrypted result is:<br/>".$rsa_obj->encrypt("this is a smple text.",$key)
        ?>
    but the encrypted data cann't decrypt by c#?where is the problem?what should i do with php codes?

    thank you for your reply, i also found this article by google.but this does not meet scene,  thank you all the same.
    i have already solved the problem now,i'd like to post the Solution .infact it's so easy to use rsakey file generated by .net .
    -------------rsa.class.php-------------------
    Code Snippet
    <?php
     * Some constants
    define("BCCOMP_LARGER", 1);
    class RSA
      * PHP implementation of the RSA algorithm
      * (C) Copyright 2004 Edsko de Vries, Ireland
      * Licensed under the GNU Public License (GPL)
      * This implementation has been verified against [3]
      * (tested Java/PHP interoperability).
      * References:
      * [1] "Applied Cryptography", Bruce Schneier, John Wiley & Sons, 1996
      * [2] "Prime Number Hide-and-Seek", Brian Raiter, Muppetlabs (online)
      * [3] "The Bouncy Castle Crypto Package", Legion of the Bouncy Castle,
      *      (open source cryptography library for Java, online)
      * [4] "PKCS #1: RSA Encryption Standard", RSA Laboratories Technical Note,
      *      version 1.5, revised November 1, 1993
      * Functions that are meant to be used by the user of this PHP module.
      * Notes:
      * - $key and $modulus should be numbers in (decimal) string format
      * - $message is expected to be binary data
      * - $keylength should be a multiple of 8, and should be in bits
      * - For rsa_encrypt/rsa_sign, the length of $message should not exceed
      *   ($keylength / 8) - 11 (as mandated by [4]).
      * - rsa_encrypt and rsa_sign will automatically add padding to the message.
      *   For rsa_encrypt, this padding will consist of random values; for rsa_sign,
      *   padding will consist of the appropriate number of 0xFF values (see [4])
      * - rsa_decrypt and rsa_verify will automatically remove message padding.
      * - Blocks for decoding (rsa_decrypt, rsa_verify) should be exactly
      *   ($keylength / 8) bytes long.
      * - rsa_encrypt and rsa_verify expect a public key; rsa_decrypt and rsa_sign
      *   expect a private key.
      * rsa encrypt data
      * @param binary string $message
      * @param unknown_type $public_key
      * @param numbers $modulus
      * @param numbers $keylength
      * @return binary data
     function rsa_encrypt($message, $public_key, $modulus, $keylength)
      $padded = RSA::add_PKCS1_padding($message, true, $keylength / 8);
      $number = RSA::binary_to_number($padded);
      $encrypted = RSA::pow_mod($number, $public_key, $modulus);
      $result = RSA::number_to_binary($encrypted, $keylength / 8);
      return $result;
     function rsa_decrypt($message, $private_key, $modulus, $keylength)
      $number = RSA::binary_to_number($message);
      $decrypted = RSA::pow_mod($number, $private_key, $modulus);
      $result = RSA::number_to_binary($decrypted, $keylength / 8);
      return RSA::remove_PKCS1_padding($result, $keylength / 8);
     function rsa_sign($message, $private_key, $modulus, $keylength)
      $padded = RSA::add_PKCS1_padding($message, false, $keylength / 8);
      $number = RSA::binary_to_number($padded);
      $signed = RSA::pow_mod($number, $private_key, $modulus);
      $result = RSA::number_to_binary($signed, $keylength / 8);
      return $result;
     function rsa_verify($message, $public_key, $modulus, $keylength)
      return RSA::rsa_decrypt($message, $public_key, $modulus, $keylength);
     function rsa_kyp_verify($message, $public_key, $modulus, $keylength)
      $number = RSA::binary_to_number($message);
      $decrypted = RSA::pow_mod($number, $public_key, $modulus);
      $result = RSA::number_to_binary($decrypted, $keylength / 8);
      return RSA::remove_KYP_padding($result, $keylength / 8);
      * The actual implementation.
      * Requires BCMath support in PHP (compile with --enable-bcmath)
     // Calculate (p ^ q) mod r
     // We need some trickery to [2]:
     //   (a) Avoid calculating (p ^ q) before (p ^ q) mod r, because for typical RSA
     //       applications, (p ^ q) is going to be _WAY_ too large.
     //       (I mean, __WAY__ too large - won't fit in your computer's memory.)
     //   (b) Still be reasonably efficient.
     // We assume p, q and r are all positive, and that r is non-zero.
     // Note that the more simple algorithm of multiplying $p by itself $q times, and
     // applying "mod $r" at every step is also valid, but is O($q), whereas this
     // algorithm is O(log $q). Big difference.
     // As far as I can see, the algorithm I use is optimal; there is no redundancy
     // in the calculation of the partial results.
     function pow_mod($p, $q, $r)
      // Extract powers of 2 from $q
      $factors = array();
      $div = $q;
      $power_of_two = 0;
      while(bccomp($div, "0") == BCCOMP_LARGER)
       $rem = bcmod($div, 2);
       $div = bcdiv($div, 2);
       if($rem) array_push($factors, $power_of_two);
       $power_of_two++;
      // Calculate partial results for each factor, using each partial result as a
      // starting point for the next. This depends of the factors of two being
      // generated in increasing order.
      $partial_results = array();
      $part_res = $p;
      $idx = 0;
      foreach($factors as $factor)
       while($idx < $factor)
        $part_res = bcpow($part_res, "2");
        $part_res = bcmod($part_res, $r);
        $idx++;
       array_push($partial_results, $part_res);
      // Calculate final result
      $result = "1";
      foreach($partial_results as $part_res)
       $result = bcmul($result, $part_res);
       $result = bcmod($result, $r);
      return $result;
     // Function to add padding to a decrypted string
     // We need to know if this is a private or a public key operation [4]
     function add_PKCS1_padding($data, $isPublicKey, $blocksize)
      $pad_length = $blocksize - 3 - strlen($data);
      if($isPublicKey)
       $block_type = "\x02";
       $padding = "";
       for($i = 0; $i < $pad_length; $i++)
        $rnd = mt_rand(1, 255);
        $padding .= chr($rnd);
      else
       $block_type = "\x01";
       $padding = str_repeat("\xFF", $pad_length);
      return "\x00" . $block_type . $padding . "\x00" . $data;
     // Remove padding from a decrypted string
     // See [4] for more details.
     function remove_PKCS1_padding($data, $blocksize)
      assert(strlen($data) == $blocksize);
      $data = substr($data, 1);
      // We cannot deal with block type 0
      if($data{0} == '\0')
      die("Block type 0 not implemented.");
      // Then the block type must be 1 or 2
      assert(($data{0} == "\x01") || ($data{0} == "\x02"));
      // Remove the padding
      $offset = strpos($data, "\0", 1);
      return substr($data, $offset + 1);
     // Remove "kyp" padding
     // (Non standard)
     function remove_KYP_padding($data, $blocksize)
      assert(strlen($data) == $blocksize);
      $offset = strpos($data, "\0");
      return substr($data, 0, $offset);
     // Convert binary data to a decimal number
     function binary_to_number($data)
      $base = "256";
      $radix = "1";
      $result = "0";
      for($i = strlen($data) - 1; $i >= 0; $i--)
       $digit = ord($data{$i});
       $part_res = bcmul($digit, $radix);
       $result = bcadd($result, $part_res);
       $radix = bcmul($radix, $base);
      return $result;
     // Convert a number back into binary form
     function number_to_binary($number, $blocksize)
      $base = "256";
      $result = "";
      $div = $number;
      while($div > 0)
       $mod = bcmod($div, $base);
       $div = bcdiv($div, $base);
       $result = chr($mod) . $result;
      return str_pad($result, $blocksize, "\x00", STR_PAD_LEFT);
    ?>
    -------------RSAProcessor.class.php------------------------
    Code Snippet
    <?php
    require_once("rsa.class.php");
    class RSAProcessor
     private $public_key = null;
     private $private_key = null;
     private $modulus = null;
     private $key_length = "1024";
     public function __construct($xmlRsakey=null,$type=null)
             $xmlObj = null;
       if($xmlRsakey==null)
               $xmlObj = simplexml_load_file("xmlfile/RSAKey.xml");
              elseif($type==RSAKeyType::XMLFile)
               $xmlObj = simplexml_load_file($xmlRsakey);
              else
               $xmlObj = simplexml_load_string($xmlRsakey);
             $this->modulus = RSA::binary_to_number(base64_decode($xmlObj->Modulus));
       $this->public_key = RSA::binary_to_number(base64_decode($xmlObj->Exponent));
       $this->key_length = strlen(base64_decode($xmlObj->Modulus))*8;
      * get public key
      * @return string public key
     public function getPublicKey()
      //return base64_encode(RSA::number_to_binary($this->public_key,($this->key_length)/8));
      return $this->public_key;
     public function getPrivateKey()
      //return base64_encode(RSA::number_to_binary($this->private_key,($this->key_length)/8));
      return $this->private_key;
     public function getKeyLength()
      return $this->key_length;
     public function getModulus()
      return $this->modulus;
      * encrypt data
      * @param string $data
      * @return base64 encoded  binary string
     public function encrypt($data)
      return base64_encode(RSA::rsa_encrypt($data,$this->public_key,$this->modulus,$this->key_length));
     public function dencrypt($data)
      return RSA::rsa_decrypt($data,$this->private_key,$this->modulus,$this->key_length);
     public function sign($data)
      return RSA::rsa_sign($data,$this->private_key,$this->modulus,$this->key_length);
     public function verify($data)
      return RSA::rsa_verify($data,$this->public_key,$this->modulus,$this->key_length);
    class RSAKeyType
     const XMLFile = 0;
     const XMLString = 1;
    ?>
    -------------- encrypt data with public key-----------------
    Code Snippet
    <?php
    require_once("RSAProcessor.class.php");
    $processor = new RSAProcessor
    ("<RSAKeyValue><Modulus>m6ljoeWhmnd0oRnsVEH5iNw3B8+vKVu7v7CVfMyf6bnKEzHa62TRmT/baJiSevoI/vgm2ph/s1JrQQTaGiErHicigwSC
    Aw7+i05WFbnz7tOyiiJJVMfsdd+v7Xan9Hiud05FzxoMbM8vpiMHPEIDbGJ1MiXyupTVkz2WcMHyBoJ4S189opktZ43pviUhy0PeuWkyoU7zR54akPmK
    Yg+z5Zr1r7K8lUZ1a3TThfJGxTQR/uZMtZz/q8QF0AANVQ/eyahTv9icBzBoDuncS0Y5l3vqogW1C/ltJvhJpvSn/OgjbRjuixCAptOUmRd13sDWU95/
    x0bMq+Lg68lj2OjJ1Q==</Modulus><Exponent>AQAB</Exponent><P>zfvdBsMLlmo+4PAUYLgSV2xyyVa7ZqFjkJaAE4EbYuH24EoZjrzeiJR++D
    FUT/GUhjfZ5eZ/5e29dXwk0sKUw6nHzBdBtOPp5fr4t5SKLEcWY+J+zLUSOlhG9NUkohFf6+Miy2Y7BLpXVrcl6UwXV0ak8KkTPB2l/aIMwYj5dgc=</
    P><Q>wXV0sA3nDzoSDQA/4QSu/WIlBhkA3jZ7K7G9Z9rpP1A0vH+bZeyCIyo52u8ahGuYbubaizF1XMp+Xv3Mh2KmRbt7+UptwEwbFAUiiad2a312mqm
    j7IJd7gRjGkyzKEm+6fpNeY3NFLNVNhccBqzhNkRoM22xnvQcImD10XVAakM=</Q><DP>wd1HdCLEWCfc0DYE59a2pINUMXyo2foRTDbpifHcRZ+ojAY
    Rsc6+nsssCQnccXVMNVqBgSgEvfGYe+eAfMBX5SN5APPuioJrVGF2DsoFlZC+WPoGH0JYSoNlHO8yEDrMDaXzzH2GFHgQ1XOAged0nFbHzB1FFjJNVL5
    cxRXWu6c=</DP><DQ>QDKuCk5SwubOXqoaiJ15RHRxPNjHRPZnYVSWOgSXKn9/QJ5H/0bA2NKGaHS4JAFgkEzjcRV0kNpRnUwztymxa6qPtWZRjWK0Ca
    y6jVuZHIqB9UkeMLoCWZ3zFSMmwNPYGuUJGLFJwPjR6iU5E64C/nMs8QQR0WHIhFAQwvVZ7uk=</DQ><InverseQ>JckMSlJR10VZdnp83VPjrZ/Z+63
    CGu3tWHm7f4DJ8IwjJWr8FlCpbSwiP6a4e9Upv6bUn/tOj2gY6MMq5G5yTKm2SCRvpUKRu4NCmWAt7vlFv0Z6pkXlTOpzvVjv3v16+dIZOA5Zn+v7+r1
    xbdYdH20KRAbiBO3MfQP7s+VJJvM=</InverseQ><D>W1xrBr2hQOj1wgxWAgoK7IHbprEFrK+TnWmGA46SGPsbmHJ9fAVbY6fwHg7Wgmk4WHXLUCeLY
    /Nu0eWIISfwh60Oe3ls2WC2k4qxyeSvQDBuLNb81U7WAUT9m9E1uK4QMCP3oxs1ybM80zTh7UMNgVK0WG+fbFUomVffcWTTqW+Fu12PEIO+UR/85oq+x
    qVlTzYAEzt1OE9IhkYiRzi99ePXeH2gFltzJ/fb/7jLsDTkhM2eiYTGyOTZmBnen6c6a8b9LFTY4Bc0bGpk5ezHkub6F8p2ZgL/JgIOJMyRZICjDjs+9
    k9PTmMTFsCF6xzHY15Fg25xIDYzIyx1rrRUjQ==</D></RSAKeyValue>",RSAKeyType::XMLString);
    $rs =  $processor->encrypt("Hello,It's Works.");
    echo $rs;
    ?>
    with the front codes.you can easy to encrypt data by public key generate by .net programe.

  • Problem with RSA/AES and the wrapped Key

    Hallo!
    For a server-client communications, I would like to use a hybrid encryption.
    For this I create an object of a serializable class that contains several properties, including the data that are to be transferred from A to B (Object, encrypted by AES), and the AES key, but wrapped by RSA (byte []).
    My basic problem is, that if I send the wrapped key, I get at the destination another byte array and thus the key can not be decoded:
    java.security.InvalidKeyException: Invalid AES key length: 256 bytes
    When I look at the string representation of the byte array before sending and immediate after receiving, the byte arrays are diffrent. Why?
    Extract from the encrypt method:
    TransportObject obj = new TransportObject();
        KeyGenerator keygen = KeyGenerator.getInstance("AES");
        SecureRandom random = new SecureRandom();
        keygen.init(random);
        Key key = keygen.generateKey();
        Cipher cipher = Cipher.getInstance("RSA/ECB/NoPadding");
        cipher.init(Cipher.WRAP_MODE, publicKey);
        byte[] wrappedKey = cipher.wrap(key);
    // Here I put the byte array in the object to be transmitted
        obj.setKey(wrappedKey);Extract from the decrypt method:
    / / Here I read the byte array from the received object
    byte[] wrappedKey = obj.getKey();
    Cipher cipher = Cipher.getInstance("RSA/ECB/NoPadding");
    cipher.init(Cipher.UNWRAP_MODE, privateKey);
    Key key = cipher.unwrap(wrappedKey, "AES", Cipher.SECRET_KEY);Here is the class that is serialized:
    import java.io.Serializable;
    public class TransportObject implements Serializable {
        private static final long serialVersionUID = 5044061539587999682L;
        private byte[] key;
        private String type;
        private byte[] data;
        public static final int STRING = 1;
        public static final int INT = 2;
        public static final int CHAR = 3;
        public TransportObject() {}
        public TransportObject(byte[] key, String type, byte[] data) {
            this.key = key;
            this.type = type;
            this.data = data;
        public byte[] getKey() {
            return key;
        public void setKey(byte[] key) {
            this.key = key;
    }Sending is done via:
    TransportObject obj = rsa.encrypt(objectToSend, keys.getPublicKey());
    ObjectOutputStream os =
        new ObjectOutputStream(socket.getOutputStream());
    os.writeObject(obj);
    os.flush();Receiving via
    ois = new ObjectInputStream(
        new BufferedInputStream(socket.getInputStream()));
    TransportObject obj = (TransportObject) ois.readObject();
    Object receivedObject = rsa.decrypt(obj, keys.getPrivateKey());Somehow, I hang down here.
    Do I overlook something? Do I have an error in reasoning?
    Thanks for any help!
    Best regards
    Sebastian Gohres
    Edited by: Spencer82 on Aug 7, 2010 9:06 AM
    Edited by: Spencer82 on Aug 7, 2010 9:08 AM

    Do I overlook something? Do I have an error in reasoning?I think at least 2.
    1. Don't do this. The general problem has been solved. The solution is called TLS, and Java provides a API called the JSSE for you to use.
    2.If you insist on rolling your own, don't specify NoPadding. Use PKCS1Padding. If you are going to use NoPadding, then you must provide your own padding scheme, which you have not.

  • Rsa Decrypt Not Working.. Please Help

    Hi everyone,
         I am new to java card development. I have been trying to use RSA encryption in my Applet. I finally got the encryption working but the decryption is showing Illegal Use Error. Any kind of help is appreciated.
    public class RSAsample extends Applet{
    byte[] rsaPublic = new byte[4];
    byte[] rsaPrivate = new byte[4];
    byte[] rsaPublicMod = new byte[4];
    RSAPrivateKey pri ;
    RSAPublicKey pub ;
    private final static byte INS_ENCRYPT = (byte) 0x20;
    private final static byte INS_DECRYPT = (byte) 0x30;
    KeyPair pair ;
    private RSAsample() {
      super();
      register();
    public static void install(byte bArray[], short bOffset, byte bLength)
      throws ISOException {
      new RSAsample();
    public boolean select() {
      pair = new KeyPair(KeyPair.ALG_RSA, (short) 512);
      pair.genKeyPair();
    pri = (RSAPrivateKey) pair.getPrivate();
    pub = (RSAPublicKey) pair.getPublic();
      return super.select();
    public void deselect() {
      super.deselect();
       public void process(APDU apdu) throws ISOException {
        byte[] buffer = apdu.getBuffer();
        switch(buffer[ISO7816.OFFSET_INS])
        case INS_ENCRYPT:
        encrypt(apdu);
        break;
        case INS_DECRYPT:
        decrypt(apdu);
        break;
    private void decrypt(APDU apdu) {
      byte[] buffer = apdu.getBuffer();
      byte byteRead = (byte)(apdu.setIncomingAndReceive());
      short size = 0;
      try{
      Cipher cipher = Cipher.getInstance(Cipher.ALG_RSA_PKCS1, false);
      cipher.init(pri, Cipher.MODE_DECRYPT);
      size =  cipher.doFinal(buffer, ISO7816.OFFSET_CDATA, (short)byteRead, buffer,
      (short) 0);
      catch(CryptoException e)
      switch(e.getReason())
      case CryptoException.ILLEGAL_USE:
      ISOException.throwIt(ISO7816.SW_DATA_INVALID);
      break;
      case CryptoException.ILLEGAL_VALUE:
      ISOException.throwIt(ISO7816.SW_FILE_INVALID);
      break;
      case CryptoException.INVALID_INIT:
      ISOException.throwIt(ISO7816.SW_FILE_NOT_FOUND);
      break;
      case CryptoException.NO_SUCH_ALGORITHM:
      ISOException.throwIt(ISO7816.SW_FILE_INVALID);
      break;
      case CryptoException.UNINITIALIZED_KEY:
      ISOException.throwIt(ISO7816.SW_FILE_FULL);
      break;
      default:
      ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED);
      break;
      apdu.setOutgoing();
      apdu.setOutgoingLength(size);
      apdu.sendBytes((short)0, size);
    private void encrypt(APDU apdu) {
      byte[] buffer = apdu.getBuffer();
      byte byteRead = (byte)(apdu.setIncomingAndReceive());
      short size = 0;
      try{
      Cipher cipher = Cipher.getInstance(Cipher.ALG_RSA_PKCS1, false);
      cipher.init(pub, Cipher.MODE_ENCRYPT);
      size =  cipher.doFinal(buffer, ISO7816.OFFSET_CDATA, (short)byteRead, buffer,
      (short) 0);
      catch(CryptoException e)
      switch(e.getReason())
      case CryptoException.ILLEGAL_USE:
      ISOException.throwIt(ISO7816.SW_DATA_INVALID);
      break;
      case CryptoException.ILLEGAL_VALUE:
      ISOException.throwIt(ISO7816.SW_FILE_INVALID);
      break;
      case CryptoException.INVALID_INIT:
      ISOException.throwIt(ISO7816.SW_FILE_NOT_FOUND);
      break;
      case CryptoException.NO_SUCH_ALGORITHM:
      ISOException.throwIt(ISO7816.SW_FILE_INVALID);
      break;
      case CryptoException.UNINITIALIZED_KEY:
      ISOException.throwIt(ISO7816.SW_FILE_FULL);
      break;
      default:
      ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED);
      break;
      apdu.setOutgoing();
      apdu.setOutgoingLength(size);
      apdu.sendBytes((short)0, size);
    Also if this is wrong can you share a sample code using RSA Encryption and Decryption.
    Thanks

    Hi,
    You code looks perfectly fine.
    Looking at the error code i think you are sending some invalid data for decryption operation.
    You should send data which was encrypted using the same PublicKey other wise it will fail while matching the Padding or Data Blocks.
    For better understanding Encrypt some data and immediately use the output data for Decrypt operation and it should work fine.
    Let me know if you face any difficulties.
    BR,
    PPT

  • No luck with RSA and existing cert

    I want to encrypt data in my software, data which will be sent to me by the user, in such a way that only I can decrypt it. This seems to call for asymmetric encryption (only the public key would be embedded in the software), so I am trying to use RSA.
    Specifically I am trying to encrypt and decrypt data using the key pairs found in a cert that we bought from a cert authority. The cert says that key is a "Sun RSA public key, 1024 bits". In the following test, I encrypt using the cert's public key and decrypt using the same, for want of a method to return the private key but the results are the same if I initialize the cipher for decryption with the cert itself (which presumably contains the private key).
            Key key = cert.getPublicKey();
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] enc = cipher.doFinal(test.getBytes());
            cipher.init(Cipher.DECRYPT_MODE, key);
            byte[] dec = cipher.doFinal(enc);but at the decyrption stage I get the following error:
    Exception in thread "main" javax.crypto.BadPaddingException: Data must start with zero.which I don't know what to make of. It seems to me that I am following the (rather scant) instructions to the letter. If I specify "RSA/ECB/NoPadding" as the transformation I don't get the above error but the roundtrip fails to recreate the original string.
    Furthermore, as I said before, I wanted to use public key encryption because I must include the encryption key in the software and I do not want it to be sufficient to decrypt the cipher. I was hoping that with RSA you'd encrypt using the public key but that you'd need either the secret key or the whole cert to decrypt. However the Javadocs do not say so explicitely and I am left unsure as to how this works exactly. Can anyone shed some light?

    I agree, the documentation is inadequate. Have you also looked at the JCE reference (http://java.sun.com/j2se/1.5.0/docs/guide/security/jce/JCERefGuide.html)? This expands a lot on the javadocs for the classes. It might also help to learn more about cryptography; one book that others recommend is "Practical Cryptography" by Ferguson and Schneier.
    I think the one key misunderstanding you have is what is in a certificate. A certificate contains only the public key, some information about the identity of the owner of the private key, and a digital signature over this public key and identifying information. The private key is not in the certificate! Nor should it be. If it were, it would no longer be private and the security of the system would fall apart.
    The location of the private key depends entirely on the application that created the key pair. java's keytool, for example, stores the private key in a password protected file.
    The error you are seeing makes sense once you understand that , for an RSA cipher, the type of key, public or private, as well as the mode Cipher.ENCRYPT_MODE or Cipher.DECRYPT_MODE, determine the interpretation of the subsequent update or doFinal method calls.
    Thus in your example, your first call to cipher.doFinal gives the RSA encryption of the data, which is what you wanted. Your second, however, attempts to decrypt this encrypted data with the public key, which makes no sense in this context. It checks to see if the result is has the proper padding, which it does not. If you tell it to assume no padding, you won't get an exception but the result still won't make any sense. You need to init the cipher with the private key for the second part.

  • RSA decryption Error: Data must start with zero

    Because of some reasons, I tried to use RSA as a block cipher to encrypt/decrypt a large file. When I debug my program, there some errors are shown as below:
    javax.crypto.BadPaddingException: Data must start with zero
         at sun.security.rsa.RSAPadding.unpadV15(Unknown Source)
         at sun.security.rsa.RSAPadding.unpad(Unknown Source)
         at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:356)
         at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:394)
         at javax.crypto.Cipher.doFinal(Cipher.java:2299)
         at RSA.RRSSA.main(RRSSA.java:114)
    From breakpoint, I think the problem is the decrypt operation, and Cipher.doFinal() can not be operated correctly.
    I searched this problem from google, many people met the same problem with me, but most of them didn't got an answer.
    The source code is :
    Key generation:
    package RSA;
    import java.io.FileOutputStream;
    import java.io.ObjectOutputStream;
    import java.security.KeyPair;
    import java.security.KeyPairGenerator;
    import java.security.PrivateKey;
    import java.security.PublicKey;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    public class GenKey {
          * @param args
                     * @author tang
         public static void main(String[] args) {
              // TODO Auto-generated method stub
                 try {
                      KeyPairGenerator KPG = KeyPairGenerator.getInstance("RSA");
                      KPG.initialize(1024);
                      KeyPair KP=KPG.genKeyPair();
                      PublicKey pbKey=KP.getPublic();
                      PrivateKey prKey=KP.getPrivate();
                      //byte[] publickey = decryptBASE64(pbKey);
                      //save public key
                      FileOutputStream out=new FileOutputStream("RSAPublic.dat");
                      ObjectOutputStream fileOut=new ObjectOutputStream(out);
                      fileOut.writeObject(pbKey);
                      //save private key
                          FileOutputStream outPrivate=new FileOutputStream("RSAPrivate.dat");
                      ObjectOutputStream privateOut=new ObjectOutputStream(outPrivate);
                                 privateOut.writeObject(prKey)
         }Encrypte / Decrypt
    package RSA;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.ObjectInputStream;
    import java.security.Key;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.crypto.Cipher;
    //import sun.misc.BASE64Decoder;
    //import sun.misc.BASE64Encoder;
    public class RRSSA {
          * @param args
         public static void main(String[] argv) {
              // TODO Auto-generated method stub
                //File used to encrypt/decrypt
                 String dataFileName = argv[0];
                 //encrypt/decrypt: operation mode
                 String opMode = argv[1];
                 String keyFileName = null;
                 //Key file
                 if (opMode.equalsIgnoreCase("encrypt")) {
                 keyFileName = "RSAPublic.dat";
                 } else {
                 keyFileName = "RSAPrivate.dat";
                 try {
                 FileInputStream keyFIS = new FileInputStream(keyFileName);
                 ObjectInputStream OIS = new ObjectInputStream(keyFIS);
                 Key key = (Key) OIS.readObject();
                 Cipher cp = Cipher.getInstance("RSA/ECB/PKCS1Padding");//
                 if (opMode.equalsIgnoreCase("encrypt")) {
                 cp.init(Cipher.ENCRYPT_MODE, key);
                 } else if (opMode.equalsIgnoreCase("decrypt")) {
                 cp.init(Cipher.DECRYPT_MODE, key);
                 } else {
                 return;
                 FileInputStream dataFIS = new FileInputStream(dataFileName);
                 int size = dataFIS.available();
                 byte[] encryptByte = new byte[size];
                 dataFIS.read(encryptByte);
                 if (opMode.equalsIgnoreCase("encrypt")) {
                 FileOutputStream FOS = new FileOutputStream("cipher.txt");
                 //RSA Block size
                 //int blockSize = cp.getBlockSize();
                 int blockSize = 64 ;
                 int outputBlockSize = cp.getOutputSize(encryptByte.length);
                 /*if (blockSize == 0)
                      System.out.println("BLOCK SIZE ERROR!");       
                 }else
                 int leavedSize = encryptByte.length % blockSize;
                 int blocksNum = leavedSize == 0 ? encryptByte.length / blockSize
                 : encryptByte.length / blockSize + 1;
                 byte[] cipherData = new byte[outputBlockSize*blocksNum];
                 //encrypt each block
                 for (int i = 0; i < blocksNum; i++) {
                 if ((encryptByte.length - i * blockSize) > blockSize) {
                 cp.doFinal(encryptByte, i * blockSize, blockSize, cipherData, i * outputBlockSize);
                 } else {
                 cp.doFinal(encryptByte, i * blockSize, encryptByte.length - i * blockSize, cipherData, i * outputBlockSize);
                 //byte[] cipherData = cp.doFinal(encryptByte);
                 //BASE64Encoder encoder = new BASE64Encoder();
                 //String encryptedData = encoder.encode(cipherData);
                 //cipherData = encryptedData.getBytes();
                 FOS.write(cipherData);
                 FOS.close();
                 } else {
                FileOutputStream FOS = new FileOutputStream("plaintext.txt");
                 //int blockSize = cp.getBlockSize();
                 int blockSize = 64;
                 //int j = 0;
                 //BASE64Decoder decoder = new BASE64Decoder();
                 //String encryptedData = convert(encryptByte);
                 //encryptByte = decoder.decodeBuffer(encryptedData);
                 int outputBlockSize = cp.getOutputSize(encryptByte.length);
                 int leavedSize = encryptByte.length % blockSize;
                 int blocksNum = leavedSize == 0 ? encryptByte.length / blockSize
                           : encryptByte.length / blockSize + 1;
                 byte[] plaintextData = new byte[outputBlockSize*blocksNum];
                 for (int j = 0; j < blocksNum; j++) {
                 if ((encryptByte.length - j * blockSize) > blockSize) {
                      cp.doFinal(encryptByte, j * blockSize, blockSize, plaintextData, j * outputBlockSize);
                      } else {
                      cp.doFinal(encryptByte, j * blockSize, encryptByte.length - j * blockSize, plaintextData, j * outputBlockSize);
                 FOS.write(plaintextData);
                 //FOS.write(cp.doFinal(encryptByte));
                 FOS.close();
    }Edited by: sabre150 on Aug 3, 2012 6:43 AM
    Moderator action : added [ code] tags so as to make the code readable. Please do this yourself in the future.
    Edited by: 949003 on 2012-8-3 上午5:31

    1) Why are you not closing the streams when writing the keys to the file?
    2) Each block of RSA encrypted data has size equal to the key modulus (in bytes). This means that for a key size of 1024 bits you need to read 128 bytes and not 64 bytes at a time when decrypting ( this is probably the cause of your 'Data must start with zero exception'). Since the input block size depends on the key modulus you cannot hard code this. Note - PKCS1 padding has at least 11 bytes of padding so on encrypting one can process a maximum of the key modulus in bytes less 11. Currently you have hard coded the encryption block at 64 bytes which is OK for your 1024 bits keys but will fail for keys of modulus less than about 936 bits.
    3) int size = dataFIS.available(); is not a reliable way to get the size of an input stream. If you check the Javadoc for InputStream.available() you will see that it returns the number of bytes that can be read without blocking and not the stream size.
    4) InputStream.read(byte[]) does not guarantee to read all the bytes and returns the number of bytes actually read. This means that your code to read the content of the file into an array may fail. Again check the Javadoc. To be safe you should used DataInputStream.readFully() to read a block of bytes.
    5) Reading the whole of the cleartext or ciphertext file into memory does not scale and with very large files you will run out of memory. There is no need to do this since you can use a "read a block, write the transformed block" approach.
    RSA is a very very very slow algorithm and it is not normal to encrypt the whole of a file using it. The standard approach is to perform the encryption of the file content using a symmetric algorithm such as AES using a random session key and use RSA to encrypt the session key. One then writes to the ciphertext file the RSA encrypted session key followed by the symmetric encrypted data. To make it more secure one should actually follow the extended procedure outlined in section 13.6 of Practical Cryptography by Ferguson and Schneier.

Maybe you are looking for