Is it possible to load in a KeyStore using JFileChooser? - java

Hi I am developing a chat program that will use keystores in java. At the moment you can load the keystore through a command line argument in the terminal. The program would be started as follows java Chat /keystore TEST.keystore - main method
public static void main(String[] args) {
int arg_length = args.length;
switch (arg_length) {
case 1:
if (args[0].equalsIgnoreCase("/keystore")) {
keystore = args[1];
File test = new File(keystore);
if (!test.exists()) {
displayHelpInformation();
}
} else {
displayHelpInformation();
}
break;
}
Chat my_server = new Chat(port);
}
Keystore is declared as a string and as you can see below I load the keystore from the given input stream.
private SSLServerSocketFactory getSSLServerSocketFactory() {
SSLContext ctx = null;
try {
KeyManagerFactory kmf;
TrustManagerFactory tmf;
KeyStore ks;
char[] password = "password".toCharArray();
// Returns a SSLContext object that implements the specified secure
// socket protocol.
ctx = SSLContext.getInstance("TLS");
kmf = KeyManagerFactory.getInstance(KeyManagerFactory
.getDefaultAlgorithm());
tmf = TrustManagerFactory.getInstance(TrustManagerFactory
.getDefaultAlgorithm());
// returns keystore object of type Java KeyStore
ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream(keystore), password);
kmf.init(ks, password);
tmf.init(ks);
ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
} catch (Exception e) {
e.printStackTrace();
}
return ctx.getServerSocketFactory();
}
What I am trying to do is allow the user to select the keystore using JFileChooser in the main window instead of using command line arguments? Is this possible? I am concerned about the fact that the keystore has a password.

You can do whatever you want with JFileChooser... I've been using it a lot lately, it's not perfect, but it's useful.
My Example would go like this:
public boolean openFile() {
JFileChooser jfc = new JFileChooser();
// OPTIONAL : if you would like to make the choices only *.keystore
FileFilter ff = new ExtensionFileFilter("KeyStore Files", new String[] { "keystore" });
jfc.setFileFilter(ff);
// END OF OPTIONAL
jfc.setCurrentDirectory(new File(".")); // base folder
jfc.setDialogTitle("Choose a KeyStore");
int jfcReturnValue = jfc.showOpenDialog(parentFrame);
if (jfcReturnValue == JFileChooser.APPROVE_OPTION) {
// sourceFile here would be the *.keystore file selected
File sourceFile = jfc.getSelectedFile();
} else {
System.out.println("Openning a file cancelled.");
return false;
}
return true;
}
You can change the return type to File if you want the method to return the File, but I usually just send true or false as notification of success or failure.
As for the password part. If you use ks.load(new FileInputStream(keystore), password); with success, then passing to it the File you got from JFileChooser will work as well.
OPTIONAL CLASS:
class ExtensionFileFilter extends FileFilter {
String description;
String extensions[];
public ExtensionFileFilter(String description, String extension) {
this(description, new String[] { extension });
}
public ExtensionFileFilter(String description, String extensions[]) {
if (description == null) {
this.description = extensions[0];
} else {
this.description = description;
}
this.extensions = (String[]) extensions.clone();
toLower(this.extensions);
}
private void toLower(String array[]) {
for (int i = 0, n = array.length; i < n; i++) {
array[i] = array[i].toLowerCase();
}
}
public String getDescription() {
return description;
}
public boolean accept(File file) {
if (file.isDirectory()) {
return true;
} else {
String path = file.getAbsolutePath().toLowerCase();
for (int i = 0, n = extensions.length; i < n; i++) {
String extension = extensions[i];
if ((path.endsWith(extension) && (path.charAt(path.length() - extension.length() - 1)) == '.')) {
return true;
}
}
}
return false;
}
}

Related

Read SubjectAlternativeNames from Certificate using Bouncy-Castle Library

I am using bouncy-castle library to make a TLS-Handshake with an Web-Server and grab the public certificate. Below is my code
private org.bouncycastle.asn1.x509.Certificate[] certificateList;
public static void main(String... args) {
new BCMain().testBCTLS();
}
private void testBCTLS() {
try {
Socket s = new Socket(InetAddress.getByName(WEB_SERVER), WEB_SERVER_PORT);
//TlsProtocolHandler tlsHandler = new TlsProtocolHandler(s.getInputStream(), s.getOutputStream());
TlsClientProtocol protocol = new TlsClientProtocol(s.getInputStream(), s.getOutputStream(), new SecureRandom());
TlsClient client = new DefaultTlsClient() {
private Boolean connectionStatus = Boolean.FALSE;
#Override
public TlsAuthentication getAuthentication() throws IOException {
return new ServerOnlyTlsAuthentication() {
public void notifyServerCertificate(Certificate serverCertificate)
throws IOException {
certificateList = serverCertificate.getCertificateList();
}
};
}
#Override
public Hashtable getClientExtensions() throws IOException {
Hashtable clientExtensions = super.getClientExtensions();
clientExtensions = TlsExtensionsUtils.ensureExtensionsInitialised(clientExtensions);
Vector<ServerName> serverNames = new Vector(1);
serverNames.add(new ServerName(NameType.host_name, SNI_HOST_NAME));
TlsExtensionsUtils.addServerNameExtension(clientExtensions, new ServerNameList(serverNames));
return clientExtensions;
}
public Boolean getConnectionStatus() {
return connectionStatus;
}
};
protocol.connect(client);
if (this.certificateList!=null) {
org.bouncycastle.asn1.x509.Certificate certificate = certificateList[0];
System.out.println(certificate.getSubject());
}
InputStream is = protocol.getInputStream();
System.out.println(is);
} catch (Exception e) {
e.printStackTrace();
}
}
I wanted to extract Subject Alternative Names from that Public certificate
The X509Certificate of JDK has method to extract SubjectAlternativeNames .. But I want to get the same from the bouncy-castle certificate.
Can some one help on this please ?
I was able to extract Subject-Alternative-Names using X509CertificateHolder and JcaX509CertificateConverter classes from BouncyCastle Library .. In continuation to the above code
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
if (this.certificateList!=null) {
org.bouncycastle.asn1.x509.Certificate certificate = certificateList[0];
X509CertificateHolder holder = new X509CertificateHolder(certificate.getEncoded());
X509Certificate x509Certificate = new JcaX509CertificateConverter().getCertificate(holder);
Collection<List<?>> sanCollections = x509Certificate.getSubjectAlternativeNames();
}

Bouncy castle gives unknown HashAlgorithm

I am trying to use bouncy castle for DTLS Handshake.
I have generated key by following this link. I am working by extending DefaultTlsClient. It can generate client_hello packet. But when the server_hello packet arrives it gives org.bouncycastle.crypto.tls.TlsFatalAlert: internal_error(80) Caused by: java.lang.IllegalArgumentException: unknown HashAlgorithm. Can anyone give any hint?
Update:
From Wireshark: In the Certificate Request, there are 9 Signature Hash Algorithms. One of them is rsa_pss_sha256(0x0804). In the public static Digest createHash(short hashAlgorithm) function in TlsUtils.java there is no matching for it. That's why it is giving Unknown hash Algorithm. What does that mean? Using Bouncy Castle, is it possible to establish DTLS with that server?
Here is the code for loading the keystore:
public static void initKeyStore() {
char password[] = "bbtone".toCharArray();
if( !isKeystoreLoaded) {
try {
FileInputStream fis = new FileInputStream("bbtone");
KeyMgmt key = new KeyMgmt();
key.open(fis, password);
fis.close();
crt = key.getCRT("bbtone").getEncoded();
fingerprintSHA256 = KeyMgmt.fingerprintSHA256(crt);
ArrayList<byte[]> chain = new ArrayList<byte[]>();
chain.add(crt);
java.security.cert.Certificate root = key.getCRT("root");
if (root != null) {
chain.add(root.getEncoded());
}
privateKey = key.getKEY("bbtone", password).getEncoded();
initDTLS(chain, privateKey, false);
isKeystoreLoaded = true;
} catch(FileNotFoundException e) {
e.printStackTrace();
} catch(Exception e) {
e.printStackTrace();
}
}
}
Generating private key and certificate:
public static boolean initDTLS(java.util.List<byte []> certChain, byte privateKey[], boolean pkRSA) {
try {
org.bouncycastle.asn1.x509.Certificate x509certs[] = new org.bouncycastle.asn1.x509.Certificate[certChain.size()];
for (int i = 0; i < certChain.size(); ++i) {
x509certs[i] = org.bouncycastle.asn1.x509.Certificate.getInstance(certChain.get(i));
}
dtlsCertChain = new org.bouncycastle.crypto.tls.Certificate(x509certs);
if (pkRSA) {
RSAPrivateKey rsa = RSAPrivateKey.getInstance(privateKey);
dtlsPrivateKey = new RSAPrivateCrtKeyParameters(rsa.getModulus(), rsa.getPublicExponent(),
rsa.getPrivateExponent(), rsa.getPrime1(), rsa.getPrime2(), rsa.getExponent1(),
rsa.getExponent2(), rsa.getCoefficient());
} else {
dtlsPrivateKey = PrivateKeyFactory.createKey(privateKey);
}
return true;
} catch (Exception e) {
return false;
}
}
Starting DTLS Handshake:
public void startDTLS() {
socket.connect(recvPacket.getAddress(), recvPacket.getPort());
try {
dtlsClient = new DTLSClientProtocol(new SecureRandom());
} catch (Exception e) {
e.printStackTrace();
dtlsClient = null;
return;
}
tlsClient = new DefaultTlsClient2() {
protected TlsSession session;
public TlsSession getSessionToResume()
{
return this.session;
}
public ProtocolVersion getClientVersion() {
return ProtocolVersion.DTLSv12;
}
public ProtocolVersion getMinimumVersion() {
return ProtocolVersion.DTLSv10;
}
public Hashtable getClientExtensions() throws IOException {
//see : http://bouncy-castle.1462172.n4.nabble.com/DTLS-SRTP-with-bouncycastle-1-49-td4656286.html
logger.debug("Extending getClientExtensions\n");
Hashtable table = super.getClientExtensions();
if (table == null) table = new Hashtable();
//adding the protection profiles
int[] protectionProfiles = {
SRTPProtectionProfile.SRTP_AES128_CM_HMAC_SHA1_80 //this is the only one supported for now
// SRTPProtectionProfile.SRTP_AES128_CM_HMAC_SHA1_32
// SRTPProtectionProfile.SRTP_NULL_HMAC_SHA1_32
// SRTPProtectionProfile.SRTP_NULL_HMAC_SHA1_80
};
byte mki[] = new byte[0]; //do not use mki
UseSRTPData srtpData = new UseSRTPData(protectionProfiles, mki);
TlsSRTPUtils.addUseSRTPExtension(table, srtpData);
return table;
}
public TlsAuthentication getAuthentication() throws IOException {
return new TlsAuthentication() {
public void notifyServerCertificate(org.bouncycastle.crypto.tls.Certificate serverCertificate)
throws IOException
{
//info only
}
public TlsCredentials getClientCredentials(CertificateRequest certificateRequest)
throws IOException
{
short[] certificateTypes = certificateRequest.getCertificateTypes();
if (certificateTypes == null) return null;
boolean ok = false;
for(int a=0;a<certificateTypes.length;a++) {
if (certificateTypes[a] == ClientCertificateType.rsa_sign) {
ok = true;
break;
}
}
if (!ok) return null;
SignatureAndHashAlgorithm signatureAndHashAlgorithm = null;
Vector sigAlgs = certificateRequest.getSupportedSignatureAlgorithms();
if (sigAlgs != null)
{
for (int i = 0; i < sigAlgs.size(); ++i)
{
SignatureAndHashAlgorithm sigAlg = (SignatureAndHashAlgorithm) sigAlgs.elementAt(i);
if (sigAlg.getSignature() == SignatureAlgorithm.rsa)
{
signatureAndHashAlgorithm = sigAlg;
break;
}
}
if (signatureAndHashAlgorithm == null)
{
return null;
}
}
return new DefaultTlsSignerCredentials(context, dtlsCertChain, dtlsPrivateKey, signatureAndHashAlgorithm);
}
};
}
public void notifyHandshakeComplete() throws IOException
{
logger.debug("SRTPChannel:DTLS:Client:Handshake complete");
super.notifyHandshakeComplete();
TlsSession newSession = context.getResumableSession();
if (newSession != null)
{
this.session = newSession;
}
getKeys();
}
};
try {
logger.debug("SRTPChannel:connecting to DTLS server");
dtlsTransport = dtlsClient.connect(tlsClient, new UDPTransport(socket, 1500 - 20 - 8));
} catch (Exception e) {
e.printStackTrace();
}
}
Error:
org.bouncycastle.crypto.tls.TlsFatalAlert: internal_error(80)
at org.bouncycastle.crypto.tls.DTLSClientProtocol.connect(DTLSClientProtocol.java:75)
at processor.ClientMediaHandler.startDTLS(ClientMediaHandler.java:459)
at processor.ClientMediaHandler.run(ClientMediaHandler.java:538)
Caused by: java.lang.IllegalArgumentException: unknown HashAlgorithm
at org.bouncycastle.crypto.tls.TlsUtils.createHash(TlsUtils.java:1184)
at org.bouncycastle.crypto.tls.DeferredHash.checkTrackingHash(DeferredHash.java:203)
at org.bouncycastle.crypto.tls.DeferredHash.trackHashAlgorithm(DeferredHash.java:68)
at org.bouncycastle.crypto.tls.TlsUtils.trackHashAlgorithms(TlsUtils.java:1358)
at org.bouncycastle.crypto.tls.DTLSClientProtocol.clientHandshake(DTLSClientProtocol.java:241)
at org.bouncycastle.crypto.tls.DTLSClientProtocol.connect(DTLSClientProtocol.java:60)
... 2 more
I have solved the problem using DTLS1.0. It can now finish the handshake.
I replaced
public ProtocolVersion getClientVersion() {
return ProtocolVersion.DTLSv12;
}
with the following code:
public ProtocolVersion getClientVersion() {
return ProtocolVersion.DTLSv10;
}
#Rashed, downgrading TLS version is not a good choice. There is already comment from #bbaldino but I think it should be added as answer - version 1.60 of bouncy castle has a bug. Instead of downgrading TLS, you should upgrade bouncy castle to at least 1.61
https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on

Java applet to implement Digital signature using smart card

How to sign a post(any document or text) in browser using smart card.
What I have investigated so far:
ActiveX - IE only
Silverlight - no access to certificates at all and as a plugin faces the same limitations as Java
Browser specific extensions; For example Firefox up until version 33 used to have window.crypto.signText but not anymore
local applications installed on the client - not easy to install, support, develop and update for several OS and their different versions.
Web Cryptography - "only basic cryptographic functions", no certificates support
I ran out of ideas.
All suggestions are welcome and appreciated.
i tried a java applet the code is here below. main class: Smartcard applet.java public class SmartCardSignerApplet extends Applet {
private static final String FILE_NAME_FIELD_PARAM = "fileNameField";
private static final String CERT_CHAIN_FIELD_PARAM = "certificationChainField";
private static final String SIGNATURE_FIELD_PARAM = "signatureField";
private static final String SIGN_BUTTON_CAPTION_PARAM = "signButtonCaption";
private static final String PKCS11_KEYSTORE_TYPE = "PKCS11";
private static final String X509_CERTIFICATE_TYPE = "X.509";
private static final String CERTIFICATION_CHAIN_ENCODING = "PkiPath";
private static final String DIGITAL_SIGNATURE_ALGORITHM_NAME = "SHA1withRSA";
private static final String SUN_PKCS11_PROVIDER_CLASS = "sun.security.pkcs11.SunPKCS11";
private Button mSignButton; //initialises applet public void init() {
String signButtonCaption = this.getParameter(SIGN_BUTTON_CAPTION_PARAM);
mSignButton = new Button(signButtonCaption);
mSignButton.setLocation(0, 0);
Dimension appletSize = this.getSize();
mSignButton.setSize(appletSize);
mSignButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
signSelectedFile();
}
});
this.setLayout(null);
this.add(mSignButton);
} \\ signing the file private void signSelectedFile() {
try {
// Get the file name to be signed from the form in the HTML document
JSObject browserWindow = JSObject.getWindow(this);
JSObject mainForm = (JSObject) browserWindow.eval("document.forms[0]");
String fileNameFieldName = this.getParameter(FILE_NAME_FIELD_PARAM);
JSObject fileNameField = (JSObject) mainForm.getMember(fileNameFieldName);
String fileName = (String) fileNameField.getMember("value");
// Perform the actual file signing
CertificationChainAndSignatureBase64 signingResult = signFile(fileName);
if (signingResult != null) {
// Document signed. Fill the certificate and signature fields
String certChainFieldName = this.getParameter(CERT_CHAIN_FIELD_PARAM);
JSObject certChainField = (JSObject) mainForm.getMember(certChainFieldName);
certChainField.setMember("value", signingResult.mCertificationChain);
String signatureFieldName = this.getParameter(SIGNATURE_FIELD_PARAM);
JSObject signatureField = (JSObject) mainForm.getMember(signatureFieldName);
signatureField.setMember("value", signingResult.mSignature);
} else {
// User canceled signing
}
}
catch (DocumentSignException dse) {
// Document signing failed. Display error message
String errorMessage = dse.getMessage();
JOptionPane.showMessageDialog(this, errorMessage);
}
catch (SecurityException se) {
se.printStackTrace();
JOptionPane.showMessageDialog(this,
"Unable to access the local file system.\n" +
"This applet should be started with full security permissions.\n" +
"Please accept to trust this applet when the Java Plug-In ask you.");
}
catch (JSException jse) {
jse.printStackTrace();
JOptionPane.showMessageDialog(this,
"Unable to access some of the fields of the\n" +
"HTML form. Please check the applet parameters.");
}
catch (Exception e) {
e.printStackTrace();
JOptionPane.showMessageDialog(this, "Unexpected error: " + e.getMessage());
}
}
private CertificationChainAndSignatureBase64 signFile(String aFileName)
throws DocumentSignException {
// Load the file for signing
byte[] documentToSign = null;
try {
documentToSign = readFileInByteArray(aFileName);
} catch (IOException ioex) {
String errorMessage = "Can not read the file for signing " + aFileName + ".";
throw new DocumentSignException(errorMessage, ioex);
}
// Show a dialog for choosing PKCS#11 implementation library and smart card PIN
PKCS11LibraryFileAndPINCodeDialog pkcs11Dialog =
new PKCS11LibraryFileAndPINCodeDialog();
boolean dialogConfirmed;
try {
dialogConfirmed = pkcs11Dialog.run();
} finally {
pkcs11Dialog.dispose();
}
if (dialogConfirmed) {
String oldButtonLabel = mSignButton.getLabel();
mSignButton.setLabel("Working...");
mSignButton.setEnabled(false);
try {
String pkcs11LibraryFileName = pkcs11Dialog.getLibraryFileName();
String pinCode = pkcs11Dialog.getSmartCardPINCode();
// Do the actual signing of the document with the smart card
CertificationChainAndSignatureBase64 signingResult =
signDocument(documentToSign, pkcs11LibraryFileName, pinCode);
return signingResult;
} finally {
mSignButton.setLabel(oldButtonLabel);
mSignButton.setEnabled(true);
}
}
else {
return null;
}
}
private CertificationChainAndSignatureBase64 signDocument(
byte[] aDocumentToSign, String aPkcs11LibraryFileName, String aPinCode)
throws DocumentSignException {
if (aPkcs11LibraryFileName.length() == 0) {
String errorMessage = "It is mandatory to choose a PCKS#11 native " +
"implementation library for for smart card (.dll or .so file)!";
throw new DocumentSignException(errorMessage);
}
// Load the keystore from the smart card using the specified PIN code
KeyStore userKeyStore = null;
try {
userKeyStore = loadKeyStoreFromSmartCard(aPkcs11LibraryFileName, aPinCode);
} catch (Exception ex) {
String errorMessage = "Can not read the keystore from the smart card.\n" +
"Possible reasons:\n" +
" - The smart card reader in not connected.\n" +
" - The smart card is not inserted.\n" +
" - The PKCS#11 implementation library is invalid.\n" +
" - The PIN for the smart card is incorrect.\n" +
"Problem details: " + ex.getMessage();
throw new DocumentSignException(errorMessage, ex);
}
// Get the private key and its certification chain from the keystore
PrivateKeyAndCertChain privateKeyAndCertChain = null;
try {
privateKeyAndCertChain =
getPrivateKeyAndCertChain(userKeyStore);
} catch (GeneralSecurityException gsex) {
String errorMessage = "Can not extract the private key and " +
"certificate from the smart card. Reason: " + gsex.getMessage();
throw new DocumentSignException(errorMessage, gsex);
}
// Check if the private key is available
PrivateKey privateKey = privateKeyAndCertChain.mPrivateKey;
if (privateKey == null) {
String errorMessage = "Can not find the private key on the smart card.";
throw new DocumentSignException(errorMessage);
}
// Check if X.509 certification chain is available
Certificate[] certChain = privateKeyAndCertChain.mCertificationChain;
if (certChain == null) {
String errorMessage = "Can not find the certificate on the smart card.";
throw new DocumentSignException(errorMessage);
}
// Create the result object
CertificationChainAndSignatureBase64 signingResult =
new CertificationChainAndSignatureBase64();
// Save X.509 certification chain in the result encoded in Base64
try {
signingResult.mCertificationChain = encodeX509CertChainToBase64(certChain);
}
catch (CertificateException cee) {
String errorMessage = "Invalid certificate on the smart card.";
throw new DocumentSignException(errorMessage);
}
// Calculate the digital signature of the file,
// encode it in Base64 and save it in the result
try {
byte[] digitalSignature = signDocument(aDocumentToSign, privateKey);
signingResult.mSignature = Base64Utils.base64Encode(digitalSignature);
} catch (GeneralSecurityException gsex) {
String errorMessage = "File signing failed.\n" +
"Problem details: " + gsex.getMessage();
throw new DocumentSignException(errorMessage, gsex);
}
return signingResult;
}
/**
* Loads the keystore from the smart card using its PKCS#11 implementation
* library and the Sun PKCS#11 security provider. The PIN code for accessing
* the smart card is required.
*/
private KeyStore loadKeyStoreFromSmartCard(String aPKCS11LibraryFileName,
String aSmartCardPIN)
throws GeneralSecurityException, IOException {
// First configure the Sun PKCS#11 provider. It requires a stream (or file)
// containing the configuration parameters - "name" and "library".
String pkcs11ConfigSettings =
"name = SmartCard\n" + "library = " + aPKCS11LibraryFileName;
byte[] pkcs11ConfigBytes = pkcs11ConfigSettings.getBytes();
ByteArrayInputStream confStream = new ByteArrayInputStream(pkcs11ConfigBytes);
// Instantiate the provider dynamically with Java reflection
try {
Class sunPkcs11Class = Class.forName(SUN_PKCS11_PROVIDER_CLASS);
Constructor pkcs11Constr = sunPkcs11Class.getConstructor(
java.io.InputStream.class);
Provider pkcs11Provider = (Provider) pkcs11Constr.newInstance(confStream);
Security.addProvider(pkcs11Provider);
} catch (Exception e) {
throw new KeyStoreException("Can initialize Sun PKCS#11 security " +
"provider. Reason: " + e.getCause().getMessage());
}
// Read the keystore form the smart card
char[] pin = aSmartCardPIN.toCharArray();
KeyStore keyStore = KeyStore.getInstance(PKCS11_KEYSTORE_TYPE);
keyStore.load(null, pin);
return keyStore;
}
/**
* #return private key and certification chain corresponding to it, extracted from
* given keystore. The keystore is considered to have only one entry that contains
* both certification chain and its corresponding private key. If the keystore has
* no entries, an exception is thrown.
*/
private PrivateKeyAndCertChain getPrivateKeyAndCertChain(
KeyStore aKeyStore)
throws GeneralSecurityException {
Enumeration aliasesEnum = aKeyStore.aliases();
if (aliasesEnum.hasMoreElements()) {
String alias = (String)aliasesEnum.nextElement();
Certificate[] certificationChain = aKeyStore.getCertificateChain(alias);
PrivateKey privateKey = (PrivateKey) aKeyStore.getKey(alias, null);
PrivateKeyAndCertChain result = new PrivateKeyAndCertChain();
result.mPrivateKey = privateKey;
result.mCertificationChain = certificationChain;
return result;
} else {
throw new KeyStoreException("The keystore is empty!");
}
}
/**
* #return Base64-encoded ASN.1 DER representation of given X.509 certification
* chain.
*/
private String encodeX509CertChainToBase64(Certificate[] aCertificationChain)
throws CertificateException {
List certList = Arrays.asList(aCertificationChain);
CertificateFactory certFactory =
CertificateFactory.getInstance(X509_CERTIFICATE_TYPE);
CertPath certPath = certFactory.generateCertPath(certList);
byte[] certPathEncoded = certPath.getEncoded(CERTIFICATION_CHAIN_ENCODING);
String base64encodedCertChain = Base64Utils.base64Encode(certPathEncoded);
return base64encodedCertChain;
}
/**
* Reads the specified file into a byte array.
*/
private byte[] readFileInByteArray(String aFileName)
throws IOException {
File file = new File(aFileName);
FileInputStream fileStream = new FileInputStream(file);
try {
int fileSize = (int) file.length();
byte[] data = new byte[fileSize];
int bytesRead = 0;
while (bytesRead < fileSize) {
bytesRead += fileStream.read(data, bytesRead, fileSize-bytesRead);
}
return data;
}
finally {
fileStream.close();
}
}
/**
* Signs given document with a given private key.
*/
private byte[] signDocument(byte[] aDocument, PrivateKey aPrivateKey)
throws GeneralSecurityException {
Signature signatureAlgorithm =
Signature.getInstance(DIGITAL_SIGNATURE_ALGORITHM_NAME);
signatureAlgorithm.initSign(aPrivateKey);
signatureAlgorithm.update(aDocument);
byte[] digitalSignature = signatureAlgorithm.sign();
return digitalSignature;
}
/**
* Data structure that holds a pair of private key and
* certification chain corresponding to this private key.
*/
static class PrivateKeyAndCertChain {
public PrivateKey mPrivateKey;
public Certificate[] mCertificationChain;
}
/**
* Data structure that holds a pair of Base64-encoded
* certification chain and digital signature.
*/
static class CertificationChainAndSignatureBase64 {
public String mCertificationChain = null;
public String mSignature = null;
}
/**
* Exception class used for document signing errors.
*/
static class DocumentSignException extends Exception {
public DocumentSignException(String aMessage) {
super(aMessage);
}
public DocumentSignException(String aMessage, Throwable aCause) {
super(aMessage, aCause);
}
}
} While i run the applet i get a message for ckr operations not found . any help?

transfer files from unix to windows using java

I want to get a file from unix system to my local system which is on windows using java. I'm very much new to this concept. Any ideas on how it could be done? Which is the best java API for this task?
If the Unix machine supports SFTP, JSch is an option. You could adapt the following code to meet your needs:
private static final String USER_PROMPT = "Enter username#hostname:port";
private static final boolean USE_GUI = true;
public static void main(final String[] arg) {
Session session = null;
ChannelSftp channelSftp = null;
try {
final JSch jsch = new JSch();
final String defaultInput = System.getProperty("user.name") + "#localhost:22";
String input = (USE_GUI) ? JOptionPane.showInputDialog(USER_PROMPT, defaultInput) : System.console().readLine("%s (%s): ", USER_PROMPT, defaultInput);
if (input == null || input.trim().length() == 0) {
input = defaultInput;
}
final int indexOfAt = input.indexOf('#');
final int indexOfColon = input.indexOf(':');
final String user = input.substring(0, indexOfAt);
final String host = input.substring(indexOfAt + 1, indexOfColon);
final int port = Integer.parseInt(input.substring(indexOfColon + 1));
jsch.setKnownHosts("/path/to/known_hosts");
// if you have set up authorized_keys on the server, using that identitiy
// with the code on the next line allows for password-free, trusted connections
// jsch.addIdentity("/path/to/id_rsa", "id_rsa_password");
session = jsch.getSession(user, host, 22);
final UserInfo ui = new MyUserInfo();
session.setUserInfo(ui);
session.connect();
channelSftp = (ChannelSftp) session.openChannel("sftp");
channelSftp.connect();
channelSftp.get("/remotepath/remotefile.txt", "/localpath/localfile.txt");
} finally {
if (channelSftp != null) {
channelSftp.exit();
}
if (session != null) {
session.disconnect();
}
}
}
public static class MyUserInfo implements UserInfo {
private String password;
#Override
public String getPassword() {
return password;
}
#Override
public boolean promptYesNo(final String str) {
final Object[] options = {"yes", "no"};
final boolean yesNo = (USE_GUI) ? JOptionPane.showOptionDialog(null, str, "Warning", JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]) == 0 : System.console().readLine("Enter y or n: ").equals("y");
return yesNo;
}
#Override
public String getPassphrase() {
return null;
}
#Override
public boolean promptPassphrase(final String message) {
return true;
}
#Override
public boolean promptPassword(final String message) {
if (!USE_GUI) {
password = new String(System.console().readPassword("Password: "));
return true;
} else {
final JTextField passwordField = new JPasswordField(20);
final Object[] ob = {passwordField};
final int result = JOptionPane.showConfirmDialog(null, ob, message, JOptionPane.OK_CANCEL_OPTION);
if (result == JOptionPane.OK_OPTION) {
password = passwordField.getText();
return true;
} else {
return false;
}
}
}
#Override
public void showMessage(final String message) {
if (!USE_GUI) {
System.console().printf(message);
} else {
JOptionPane.showMessageDialog(null, message);
}
}
}
I have found JSch to be very useful and straight foreword. Below is a snippet of code written to put all .txt files in a given folder on the sftp server.
public static void sftpConnection() {
// Object Declaration.
JSch jsch = new JSch();
Session session = null;
Channel channel = null;
// Variable Declaration.
String user = "foo";
String host = "10.9.8.7";
Integer port = 22;
String password = "test123";
String watchFolder = "\\localhost\textfiles";
String outputDir = "/remote/textFolder/";
String filemask = "*.txt";
try {
session = jsch.getSession(user, host, port);
/*
* StrictHostKeyChecking Indicates what to do if the server's host
* key changed or the server is unknown. One of yes (refuse connection),
* ask (ask the user whether to add/change the key) and no
* (always insert the new key).
*/
session.setConfig("StrictHostKeyChecking", "no");
session.setPassword(password);
session.connect();
channel = session.openChannel("sftp");
channel.connect();
ChannelSftp sftpChannel = (ChannelSftp)channel;
// Go through watch folder looking for files.
File[] files = findFile(watchFolder, filemask);
for(File file : files) {
// Upload file.
putFile(file, sftpChannel, outputDir);
}
} finally {
sftpChannel.exit();
session.disconnect();
}
}
public static void putFile(File file, ChannelSftp sftpChannel, String outputDir) {
FileInputStream fis = null;
try {
// Change to output directory.
sftpChannel.cd(outputDir);
// Upload file.
fis = new FileInputStream(file);
sftpChannel.put(fis, file.getName());
fis.close();
} catch{}
}
public static File[] findFile(String dirName, final String mask) {
File dir = new File(dirName);
return dir.listFiles(new FilenameFilter() {
public boolean accept(File dir, String filename)
{ return filename.endsWith(mask); }
} );
}
First thing that goes into my mind is FTP.
There are multiple choices to do that. First one simple socket communication between a java client and a server. If you want to go with this approach then follow this:
http://mrbool.com/file-transfer-between-2-computers-with-java/24516
Then there are other high level protocols implementations that can be used such as FTP, HTTP, etc
Follow a related SO post for java FTP client server: FTP client server model for file transfer in Java

SSHD Java example

Can anyone point me to some example code for using SSHD to access a server and execute some commands from a JAVA application. I have looked through the Apache SSHD website and downloads and have not found anything useful yet as far as documentation and example code. I also googled SSHD example code and was unsuccessful.
This one can run,I have checked it.I just delete the import.
version apache sshd-core-0.7.0.jar
public class SshClient extends AbstractFactoryManager implements ClientFactoryManager {
protected IoConnector connector;
protected SessionFactory sessionFactory;
private ServerKeyVerifier serverKeyVerifier;
public SshClient() {
}
public SessionFactory getSessionFactory() {
return sessionFactory;
}
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public ServerKeyVerifier getServerKeyVerifier() {
return serverKeyVerifier;
}
public void setServerKeyVerifier(ServerKeyVerifier serverKeyVerifier) {
this.serverKeyVerifier = serverKeyVerifier;
}
public void start() {
// Register the additional agent forwarding channel if needed
if (getAgentFactory() != null) {
List<NamedFactory<Channel>> factories = getChannelFactories();
if (factories == null) {
factories = new ArrayList<NamedFactory<Channel>>();
} else {
factories = new ArrayList<NamedFactory<Channel>>(factories);
}
factories.add(getAgentFactory().getChannelForwardingFactory());
setChannelFactories(factories);
}
connector = createAcceptor();
if (sessionFactory == null) {
sessionFactory = new SessionFactory();
}
sessionFactory.setClient(this);
connector.setHandler(sessionFactory);
}
protected NioSocketConnector createAcceptor() {
return new NioSocketConnector(getNioWorkers());
}
public void stop() {
connector.dispose();
connector = null;
}
public ConnectFuture connect(String host, int port) throws Exception {
assert host != null;
assert port >= 0;
if (connector == null) {
throw new IllegalStateException("SshClient not started. Please call start() method before connecting to a server");
}
SocketAddress address = new InetSocketAddress(host, port);
return connect(address);
}
public ConnectFuture connect(SocketAddress address) throws Exception {
assert address != null;
if (connector == null) {
throw new IllegalStateException("SshClient not started. Please call start() method before connecting to a server");
}
final ConnectFuture connectFuture = new DefaultConnectFuture(null);
connector.connect(address).addListener(new IoFutureListener<org.apache.mina.core.future.ConnectFuture>() {
public void operationComplete(org.apache.mina.core.future.ConnectFuture future) {
if (future.isCanceled()) {
connectFuture.cancel();
} else if (future.getException() != null) {
connectFuture.setException(future.getException());
} else {
ClientSessionImpl session = (ClientSessionImpl) AbstractSession.getSession(future.getSession());
connectFuture.setSession(session);
}
}
});
return connectFuture;
}
/**
* Setup a default client. The client does not require any additional setup.
*
* #return a newly create SSH client
*/
public static SshClient setUpDefaultClient() {
SshClient client = new SshClient();
// DHG14 uses 2048 bits key which are not supported by the default JCE provider
if (SecurityUtils.isBouncyCastleRegistered()) {
client.setKeyExchangeFactories(Arrays.<NamedFactory<KeyExchange>>asList(
new DHG14.Factory(),
new DHG1.Factory()));
client.setRandomFactory(new SingletonRandomFactory(new BouncyCastleRandom.Factory()));
} else {
client.setKeyExchangeFactories(Arrays.<NamedFactory<KeyExchange>>asList(
new DHG1.Factory()));
client.setRandomFactory(new SingletonRandomFactory(new JceRandom.Factory()));
}
setUpDefaultCiphers(client);
// Compression is not enabled by default
// client.setCompressionFactories(Arrays.<NamedFactory<Compression>>asList(
// new CompressionNone.Factory(),
// new CompressionZlib.Factory(),
// new CompressionDelayedZlib.Factory()));
client.setCompressionFactories(Arrays.<NamedFactory<Compression>>asList(
new CompressionNone.Factory()));
client.setMacFactories(Arrays.<NamedFactory<Mac>>asList(
new HMACMD5.Factory(),
new HMACSHA1.Factory(),
new HMACMD596.Factory(),
new HMACSHA196.Factory()));
client.setSignatureFactories(Arrays.<NamedFactory<Signature>>asList(
new SignatureDSA.Factory(),
new SignatureRSA.Factory()));
return client;
}
private static void setUpDefaultCiphers(SshClient client) {
List<NamedFactory<Cipher>> avail = new LinkedList<NamedFactory<Cipher>>();
avail.add(new AES128CBC.Factory());
avail.add(new TripleDESCBC.Factory());
avail.add(new BlowfishCBC.Factory());
avail.add(new AES192CBC.Factory());
avail.add(new AES256CBC.Factory());
for (Iterator<NamedFactory<Cipher>> i = avail.iterator(); i.hasNext();) {
final NamedFactory<Cipher> f = i.next();
try {
final Cipher c = f.create();
final byte[] key = new byte[c.getBlockSize()];
final byte[] iv = new byte[c.getIVSize()];
c.init(Cipher.Mode.Encrypt, key, iv);
} catch (InvalidKeyException e) {
i.remove();
} catch (Exception e) {
i.remove();
}
}
client.setCipherFactories(avail);
}
/*=================================
Main class implementation
*=================================*/
public static void main(String[] args) throws Exception {
int port = 22;
String host = null;
String login = System.getProperty("user.name");
boolean agentForward = false;
List<String> command = null;
int logLevel = 0;
boolean error = false;
for (int i = 0; i < args.length; i++) {
if (command == null && "-p".equals(args[i])) {
if (i + 1 >= args.length) {
System.err.println("option requires an argument: " + args[i]);
error = true;
break;
}
port = Integer.parseInt(args[++i]);
} else if (command == null && "-l".equals(args[i])) {
if (i + 1 >= args.length) {
System.err.println("option requires an argument: " + args[i]);
error = true;
break;
}
login = args[++i];
} else if (command == null && "-v".equals(args[i])) {
logLevel = 1;
} else if (command == null && "-vv".equals(args[i])) {
logLevel = 2;
} else if (command == null && "-vvv".equals(args[i])) {
logLevel = 3;
} else if ("-A".equals(args[i])) {
agentForward = true;
} else if ("-a".equals(args[i])) {
agentForward = false;
} else if (command == null && args[i].startsWith("-")) {
System.err.println("illegal option: " + args[i]);
error = true;
break;
} else {
if (host == null) {
host = args[i];
} else {
if (command == null) {
command = new ArrayList<String>();
}
command.add(args[i]);
}
}
}
if (host == null) {
System.err.println("hostname required");
error = true;
}
if (error) {
System.err.println("usage: ssh [-A|-a] [-v[v][v]] [-l login] [-p port] hostname [command]");
System.exit(-1);
}
// TODO: handle log level
SshClient client = SshClient.setUpDefaultClient();
client.start();
try {
boolean hasKeys = false;
/*
String authSock = System.getenv(SshAgent.SSH_AUTHSOCKET_ENV_NAME);
if (authSock == null) {
KeyPair[] keys = null;
AgentServer server = new AgentServer();
authSock = server.start();
List<String> files = new ArrayList<String>();
File f = new File(System.getProperty("user.home"), ".ssh/id_dsa");
if (f.exists() && f.isFile() && f.canRead()) {
files.add(f.getAbsolutePath());
}
f = new File(System.getProperty("user.home"), ".ssh/id_rsa");
if (f.exists() && f.isFile() && f.canRead()) {
files.add(f.getAbsolutePath());
}
try {
if (files.size() > 0) {
keys = new FileKeyPairProvider(files.toArray(new String[0]), new PasswordFinder() {
public char[] getPassword() {
try {
System.out.println("Enter password for private key: ");
BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
String password = r.readLine();
return password.toCharArray();
} catch (IOException e) {
return null;
}
}
}).loadKeys();
}
} catch (Exception e) {
}
SshAgent agent = new AgentClient(authSock);
for (KeyPair key : keys) {
agent.addIdentity(key, "");
}
agent.close();
}
if (authSock != null) {
SshAgent agent = new AgentClient(authSock);
hasKeys = agent.getIdentities().size() > 0;
}
client.getProperties().put(SshAgent.SSH_AUTHSOCKET_ENV_NAME, authSock);
*/
ClientSession session = client.connect(host, port).await().getSession();
int ret = ClientSession.WAIT_AUTH;
while ((ret & ClientSession.WAIT_AUTH) != 0) {
if (hasKeys) {
session.authAgent(login);
ret = session.waitFor(ClientSession.WAIT_AUTH | ClientSession.CLOSED | ClientSession.AUTHED, 0);
} else {
System.out.print("Password:");
BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
String password = r.readLine();
session.authPassword(login, password);
ret = session.waitFor(ClientSession.WAIT_AUTH | ClientSession.CLOSED | ClientSession.AUTHED, 0);
}
}
if ((ret & ClientSession.CLOSED) != 0) {
System.err.println("error");
System.exit(-1);
}
ClientChannel channel;
if (command == null) {
channel = session.createChannel(ClientChannel.CHANNEL_SHELL);
((ChannelShell) channel).setAgentForwarding(agentForward);
channel.setIn(new NoCloseInputStream(System.in));
} else {
channel = session.createChannel(ClientChannel.CHANNEL_EXEC);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Writer w = new OutputStreamWriter(baos);
for (String cmd : command) {
w.append(cmd).append(" ");
}
w.append("\n");
w.close();
channel.setIn(new ByteArrayInputStream(baos.toByteArray()));
}
channel.setOut(new NoCloseOutputStream(System.out));
channel.setErr(new NoCloseOutputStream(System.err));
channel.open().await();
channel.waitFor(ClientChannel.CLOSED, 0);
session.close(false);
} finally {
client.stop();
}
}
}
public static void main(String[] args) throws IOException, InterruptedException
{
SshClient client = SshClient.setUpDefaultClient();
client.start();
final ClientSession session = client.connect("bob", "bob.mynetwork.com", 22).await().getSession();
int authState = ClientSession.WAIT_AUTH;
while ((authState & ClientSession.WAIT_AUTH) != 0) {
session.addPasswordIdentity("bobspassword");
System.out.println("authenticating...");
final AuthFuture authFuture = session.auth();
authFuture.addListener(new SshFutureListener<AuthFuture>()
{
#Override
public void operationComplete(AuthFuture arg0)
{
System.out.println("Authentication completed with " + ( arg0.isSuccess() ? "success" : "failure"));
}
});
authState = session.waitFor(ClientSession.WAIT_AUTH | ClientSession.CLOSED | ClientSession.AUTHED, 0);
}
if ((authState & ClientSession.CLOSED) != 0) {
System.err.println("error");
System.exit(-1);
}
final ClientChannel channel = session.createShellChannel();
channel.setOut(new NoCloseOutputStream(System.out));
channel.setErr(new NoCloseOutputStream(System.err));
channel.open();
executeCommand(channel, "pwd\n");
executeCommand(channel, "ll\n");
channel.waitFor(ClientChannel.CLOSED, 0);
session.close(false);
client.stop();
}
private static void executeCommand(final ClientChannel channel, final String command) throws IOException
{
final InputStream commandInput = new ByteArrayInputStream(command.getBytes());
channel.setIn(new NoCloseInputStream(commandInput));
}
Having tracked development regarding Java support for SSH for many years now, I strongly recommend against using any Java SSH implementation. Noone cares to develop them any further. None of them has proper SSH-Agent support. And SSH without SSH-Agent, especially when running code on top of it, makes those implementations rather useless - unless you are willing to put unencrypted keys or passwords everywhere.
The best solution IMHO is to write a wrapper around the rock-solid OpenSSH implementations.

Categories

Resources