/********************************************************************************* * TotalCross Software Development Kit * * Copyright (C) 2000-2012 SuperWaba Ltda. * * All Rights Reserved * * * * This library and virtual machine 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. * * * *********************************************************************************/ package totalcross.crypto.cipher; import java.math.BigInteger; import java.security.*; import java.security.spec.*; import javax.crypto.spec.IvParameterSpec; import totalcross.crypto.*; import totalcross.crypto.NoSuchAlgorithmException; /** * This class implements the RSA cryptographic cipher. */ public class RSACipher extends Cipher { /** * Returns the name of the algorithm. * * @return "RSA". */ public final String getAlgorithm() { return "RSA"; } /** * Returns the block length. * * @return Always returns 0. */ public final int getBlockLength() { return 0; } protected final void doReset() throws NoSuchAlgorithmException, CryptoException { String transf = "RSA"; switch (chaining) { case CHAINING_NONE: transf += "/NONE"; break; case CHAINING_ECB: transf += "/ECB"; break; case CHAINING_CBC: transf += "/CBC"; break; } switch (padding) { case PADDING_NONE: transf += "/NoPadding"; break; case PADDING_PKCS1: transf += "/PKCS1Padding"; break; case PADDING_PKCS5: transf += "/PKCS5Padding"; } try { javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance(transf); cipherRef = cipher; KeyFactory factory = KeyFactory.getInstance("RSA"); if (operation == OPERATION_ENCRYPT) { RSAPublicKey pubKey = (RSAPublicKey)key; keyRef = factory.generatePublic(new RSAPublicKeySpec(new BigInteger(pubKey.getModulus()), new BigInteger(pubKey.getPublicExponent()))); } else // DECRYPT { RSAPrivateKey privKey = (RSAPrivateKey)key; keyRef = factory.generatePrivate(new RSAPrivateKeySpec(new BigInteger(privKey.getModulus()), new BigInteger(privKey.getPrivateExponent()))); } int mode = operation == OPERATION_ENCRYPT ? javax.crypto.Cipher.ENCRYPT_MODE : javax.crypto.Cipher.DECRYPT_MODE; cipher.init(mode, (java.security.Key)keyRef, iv == null ? null : new IvParameterSpec(iv)); if (iv == null) iv = cipher.getIV(); } catch (java.security.NoSuchAlgorithmException e) { throw new NoSuchAlgorithmException(e.getMessage()); } catch (GeneralSecurityException e) { throw new CryptoException(e.getMessage()); } } protected final byte[] process(byte[] data) throws CryptoException { try { javax.crypto.Cipher cipher = (javax.crypto.Cipher)cipherRef; return cipher.doFinal(data); } catch (GeneralSecurityException e) { throw new CryptoException(e.getMessage()); } } protected final boolean isKeySupported(Key key, int operation) { return (operation == OPERATION_ENCRYPT && key instanceof RSAPublicKey) || (operation == OPERATION_DECRYPT && key instanceof RSAPrivateKey); } protected final boolean isChainingSupported(int chaining) { return chaining == CHAINING_ECB; } protected final boolean isPaddingSupported(int padding) { return padding == PADDING_PKCS1; } }