I can provide more detail if necessary, but my question is basically thus:
If I'm running an openfire server that encrypts traffic using an RSA pub/priv key combo that I created (and have), is there a way (preferably in Java) to sniff packets off the wire and then decrypt them using my private key? Currently I can encrypt/decrypt a string using the following:
public class TLSDecryptTest {
Cipher Ecipher;
Cipher Dcipher;
public TLSDecryptTest(String pubpath, String privpath){
byte[] publicKeyContentsAsByteArray;
RSAPublicKey pubKey;
try {
this.Ecipher = Cipher.getInstance("RSA");
String path1 = new String("C:\\Users\\peter.marino\\Desktop\\javapub.key");
File pubFile = new File(path1);
publicKeyContentsAsByteArray = new byte[(int)pubFile.length()];
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(pubFile));
publicKeyContentsAsByteArray = new byte[(int)pubFile.length()];
bis.read(publicKeyContentsAsByteArray);
bis.close();
CertificateFactory certificateFactory = CertificateFactory.getInstance("X509");
Certificate certificate = certificateFactory.generateCertificate(new ByteArrayInputStream(publicKeyContentsAsByteArray));
pubKey = (RSAPublicKey) certificate.getPublicKey();
this.Ecipher.init(Cipher.ENCRYPT_MODE, pubKey);
} catch(Exception e) {
System.out.println("Exception" + e);
}
try {
this.Dcipher = Cipher.getInstance("RSA");
String path2 = new String("C:\\Users\\peter.marino\\Desktop\\java.key");
File privFile = new File(path2);
byte[] privateKeyContentsAsByteArray = new byte[(int)privFile.length()];
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(privFile));
privateKeyContentsAsByteArray = new byte[(int)privFile.length()];
bis.read(privateKeyContentsAsByteArray);
bis.close();
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
KeySpec ks = new PKCS8EncodedKeySpec(privateKeyContentsAsByteArray);
RSAPrivateKey privKey = (RSAPrivateKey) keyFactory.generatePrivate(ks);
System.out.println("PRIVATE KEY:::: " + new String(privKey.getEncoded()).equals(new String(privateKeyContentsAsByteArray)));
this.Dcipher.init(Cipher.DECRYPT_MODE, privKey);
} catch(Exception e) {
System.out.println("Exception" + e);
}
}
public byte[] en(byte[] decryptedMessage) throws Exception {
byte[] encryptedMessage = this.Ecipher.doFinal(decryptedMessage);
//byte[] encryptedMessage = this.Ecipher.doFinal(decryptedMessage);
return (encryptedMessage);
}
public byte[] de(byte[] encryptedMessage) throws Exception {
byte[] decryptedMessage = this.Dcipher.doFinal(encryptedMessage);
return (decryptedMessage);
}
public static void main(String args[]) throws Exception{
TLSDecryptTest t = new TLSDecryptTest(null,null);
String s = ("Testing decryption.1Testing decryption.2Testing decryption.3Testing decryption.4");
System.out.println("S: " + s);
byte[] todo = s.getBytes();
byte[] e = t.en(todo);
String es = new String(e);
System.out.println("E: " + es);
byte[] d = t.de(e);
String ds = new String(d);
System.out.println("D: " + ds);
}
}
which works fine. However, if I sniff a few packets off the wire and then try to decrypt it, I get errors. I even tried only decrypting the first 256 bytes of it, seeing as that's the limitation of my RSA key, but it still throws errors. Most notably, a BadPaddingException at the doFinal() line.
Any ideas?
Thanks in advance.
If you are talking about SSL-protected session, then man-in-the-middle attack is possible if you have a legitimate server's private key (and can obtain the certificate which is public anyway). For practical purpose you should be able to use Wireshark to spy on your traffic.
But you can't decrypt the traffic as is. Partially because it's not encrypted using public key cryptography - data is encrypted using symmetric key generated per session.
Wireshark will allow you to decrypt if you have the server's private key. Docs are here.
First, go to Edit/Preferences/Protocols/SSL, click the Edit button next to RSA Keys:
Next, click New. Fill out the form with information that describes when the key should be used. This should be the IP address and port of the server:
Your key file may or may not require a passphrase. Hit OK three times. Capture as usual.
No. With public key encryption, you can only ever decrypt with the opposite key. e.g.
encrypted with private key => decrypt with public key
encryptd with public key => decrypt with private key
consider the chaos that would happen if
encrypted with public key => decrypt with public key
were possible - since the public key is floating around "in the open" for everyone to see, you'd essentially be giftwrapping your data in saran wrap, because everyone would have the key to decrypt it already. This would completely torpedo the entire SSL security model.
Related
I was a using a custom build itext based java application for digitally signing pdf files.
Every thing was working fine for last one year but recently the size of the output signed pdf file drastically increasing up to 10 MB for just a 50kb source pdf file.
Earlier for a 50 kb file ,the output was less than 300 kb.
Kindly find the code snippets
public void sign(String src, String dest,
Certificate[] chain, PrivateKey pk,
String digestAlgorithm, String provider, MakeSignature.CryptoStandard subfilter,
String reason, String location,
Collection<CrlClient> crlList,
OcspClient ocspClient,
TSAClient tsaClient,
int estimatedSize)
throws GeneralSecurityException, IOException, DocumentException {
// Creating the reader and the stamper
PdfReader reader = new PdfReader(src);
FileOutputStream os = new FileOutputStream(dest);
PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0');
// Creating the appearance
PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
ExternalSignature pks = new PrivateKeySignature(pk, digestAlgorithm, provider);
ExternalDigest digest = new BouncyCastleDigest();
MakeSignature.signDetached(appearance, digest, pks, chain, crlList, ocspClient, tsaClient, estimatedSize, subfilter);
}
public PrivateKey getPrivateKey(String DLL,String PIN,String usage) throws GeneralSecurityException, IOException {
LoggerFactory.getInstance().setLogger(new SysoLogger());
String config = "name=eToken\n" + "library=" + DLL + "\n";
ByteArrayInputStream bais = new ByteArrayInputStream(config.getBytes());
Provider providerPKCS11 = new SunPKCS11(bais);
Security.addProvider(providerPKCS11);
//System.out.println(providerPKCS11.getName());
BouncyCastleProvider providerBC = new BouncyCastleProvider();
Security.addProvider(providerBC);
PrivateKey pk = null;
KeyStore ks = KeyStore.getInstance("PKCS11");
try{
ks.load(null, PIN.toCharArray());
String alias = (String)ks.aliases().nextElement();
java.util.Enumeration<String> aliases = ks.aliases();
while (aliases.hasMoreElements()) {
alias = aliases.nextElement();
//System.out.println(alias);
X509Certificate c = (X509Certificate) ks.getCertificate(alias);
final boolean[] keyUsage = c.getKeyUsage();
if(usage=="0" &&(keyUsage[0] || keyUsage[1]))
{
//System.out.println("Digital Signature");
pk = (PrivateKey)ks.getKey(alias, PIN.toCharArray());
this.providerPKCS11 = providerPKCS11.getName();
this.pub_key = c;
this.chain = ks.getCertificateChain(alias);
for (int i = 0; i < this.chain.length; i++) {
// System.out.println(chain[i]);
X509Certificate cert = (X509Certificate)chain[i];
String tsaUrl = CertificateUtil.getTSAURL(cert);
if (tsaUrl != null) {
tsaClient = new TSAClientBouncyCastle(tsaUrl);
break;
}
}
crlList.add(new CrlClientOnline(chain));
}
else if(usage=="2" &&keyUsage[2])
{
//System.out.println("Encryption");
pk = (PrivateKey)ks.getKey(alias, PIN.toCharArray());
this.pub_key = c;
}
//alias1=alias;
}
}
catch(Exception e)
{
System.out.println("Key Store Not loaded .. PIN entered may be incorrect");
}
return pk;
}
Main function is
token.sign("D:\\15 SAMPLE PDF FILES\\15 SAMPLE PDF FILES\\"+listOfFiles[i].getName(), "D:\\15 SAMPLE PDF FILES\\15 SAMPLE PDF FILES\\sign\\singn_"+listOfFiles[i].getName(), token.chain, PK_sign, DigestAlgorithms.SHA256, token.providerPKCS11, MakeSignature.CryptoStandard.CMS,
"Sign", "Kottayam", token.crlList, token.ocspClient, token.tsaClient, 0);
Last week our firewall changed. Is that the problem?
If the process of signing a PDF suddenly results in much bigger files than before, the reason often is related to embedded validation related information, in particular to embedded CRLs (certificate revocation lists) which may be very large.
The cause might be purely inside the PKI. E.g. if lots of certificates suddenly are revoked after the associated signature creation devices have been found to be insecure, a formerly small CRL may suddenly become very large.
It might also be a matter of connectivity. For example
if the OCSP responder of the PKI was accessible before but suddenly isn't anymore, the signing process might use the CRL instead; or
if the revocation information was not accessible at all before and suddenly is, the signing process also might start using the CRL.
As it turned out, the latter was the case here, as the OP reported:
It was because of the firewall change. Initially the server will not look for crl url and so it doesnt embedd crl since it is not connecting to internet because of the firewall authentication. Unfortunately the firewall change cleared all the authentication and hence the server got the internet access and crl embedds in the signature.
Something like this can be prevented by disallowing use of CRLs. In the case at hand, the Collection<CrlClient> crlList parameter of the sign method can simply be left empty.
Essentially, if you don't want to include CRLs or OCSP responses, don't provide the signing process with means to request them.
How i can apply custom function with tmap, or may be with tsystem. I want to decrypt crypted columns on-the-fly with my custom function. I can write all encrypted values to file, then write from file to tsystem, or tmap, and decrypt values. What is the best way for this?
Use Java routines. you can create java methods and call anywhere. for example
public static String decrypt(String encryptStr){
String decrypted = null;
try {
while(encryptStr != null){
try
{
String key = "Bar12345Bar12345"; // 128 bit key
// Create key and cipher
Key aesKey = new SecretKeySpec(key.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES");
// encrypt the text
cipher.init(Cipher.ENCRYPT_MODE, aesKey);
// for decryption
byte[] bb = new byte[encryptStr.length()];
for (int i=0; i<encryptStr.length(); i++) {
bb[i] = (byte) encryptStr.charAt(i);
}
// decrypt the text
cipher.init(Cipher.DECRYPT_MODE, aesKey);
decrypted = new String(cipher.doFinal(bb));
}
catch(Exception e)
{
e.printStackTrace();
}
}
} catch (IOException ex) {
Logger.getLogger(Snake_H.class.getName()).log(Level.SEVERE, null, ex);
}
return decrypted;
}
For encrypts follow the same kind of methods. you can call this java method at anywhere like tmap
Reference Talend Routines
If you are speaking about routines, simply call the desired method everywhere you can put some java code.
For example, as an expression for the output flow, you can have something like:yourClass.yourMethod(...)
Hope this helps.
I prepared an iphone application that gets push notification messages. I can send push message using with 2195 port , gateway.sandbox.push.apple.com and local p12 file
My application in appstore, now i'm using gateway.push.apple.com and distribution p12 file, but messages cannot reach to real application (in appstore)
Device ids are different in local and prod version, I know this so i'm trying to send new device id from .net
Same codes works in local and i can send messages but when i send push message to real application, no message reach to iphone with the same codes. I have no error during this period.
What can i do?
my c# code like below. How can i solve my problem? There is no error but message cannot reach to devices with distribution cert.
int port = 2195;
String hostname = "gateway.push.apple.com";
String certificatePath = HttpContext.Current.Server.MapPath("distribution.p12");
X509Certificate2 clientCertificate = new X509Certificate2(System.IO.File.ReadAllBytes(certificatePath), "xxx", X509KeyStorageFlags.MachineKeySet |
X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
X509Certificate2Collection certificatesCollection = new X509Certificate2Collection(clientCertificate);
TcpClient client = new TcpClient(hostname, port);
SslStream sslStream = new SslStream(client.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null);
try
{
sslStream.AuthenticateAsClient(hostname, certificatesCollection, SslProtocols.Tls, true);
}
catch (Exception e)
{
throw (e);
client.Close();
return;
}
MemoryStream memoryStream = new MemoryStream();
BinaryWriter writer = new BinaryWriter(memoryStream);
writer.Write((byte)0);
writer.Write((byte)0); //The first byte of the deviceId length (big-endian first byte)
writer.Write((byte)32); //The deviceId length (big-endian second byte)
//String deviceID = "f1430c99 910d292d 2f756294 f2f6b348 153bc215 d5404447 16b294eb fdb9496c";
writer.Write(HexStringToByteArray(deviceID.ToUpper()));
String payload = "{\"aps\":{\"alert\":\"" + Mesaj + "\",\"badge\":0,\"sound\":\"default\"}}";
writer.Write((byte)0);
writer.Write((byte)payload.Length);
byte[] b1 = System.Text.Encoding.UTF8.GetBytes(payload);
writer.Write(b1);
writer.Flush();
byte[] array = memoryStream.ToArray();
sslStream.Write(array);
sslStream.Flush();
client.Close();
After enabled your push notification in your profile appid.
Then only you can able to get device token from the running device. Based on the device token you may send notification.
development process : gateway.sandbox.push.apple.com port 2195.
distribution process : gateway.push.apple.com port 2195.
refer from this links: https://stackoverflow.com/a/10045210/510814
https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/CommunicatingWIthAPS.html
Could someone explain why this httpunit test case keeps failing in wc.getResponse with "bad file descriptor". I added the is.close() as a guess and moved it before and after the failure but that had no effect. This tests put requests to a Dropwizard app.
public class TestCircuitRequests
{
static WebConversation wc = new WebConversation();
static String url = "http://localhost:8888/funl/circuit/test.circuit1";
#Test
public void testPut() throws Exception
{
InputStream is = new FileInputStream("src/test/resources/TestCircuit.json");
WebRequest rq = new PutMethodWebRequest(url, is, "application/json");
wc.setAuthentication("FUNL", "foo", "bar");
WebResponse response = wc.getResponse(rq);
is.close();
}
No responses? So I'll try myself based on what I learned fighting this.
Httpunit is an old familiar tool that I'd use if I could. But it hasn't been updated in more than two years, so I gather its support for #PUT requests isn't right.
So I converted to Jersey-client instead. After a bunch of struggling I wound up with this code which does seem to work:
#Test
public void testPut() throws Exception
{
InputStream is = new FileInputStream("src/test/resources/TestCircuit.json");
String circuit = StreamUtil.readFully(is);
is.close();
Authenticator.setDefault(new MyAuthenticator());
ClientConfig config = new DefaultClientConfig();
Client client = Client.create(config);
com.sun.jersey.api.client.WebResource service = client.resource(url);
Builder builder = service.accept(MediaType.APPLICATION_JSON);
builder.entity(circuit, MediaType.APPLICATION_JSON);
builder.put(String.class, circuit);
return;
}
This intentionally avoids JAX-RS automatic construction of beans from JSON strings.
Hi i have got a TCP/IP Socket project.
i can send string messages to Server with Client side and i can get responses from server.
But getting one string message and sending only one string (or any other object).I wanna Encode Personel class to Byte array after send to Clients from server side.And Decode it. than get values from my class.
//SERVER SIDE CODE Connect() starts at on form load
private void Connect()
{
// start listen socket
dinleyiciSoket = new TcpListener(System.Net.IPAddress.Any, 10048);
dinleyiciSoket.Start();
Socket istemciSoketi = dinleyiciSoket.AcceptSocket();
NetworkStream agAkisi = new NetworkStream(istemciSoketi);
BinaryReader binaryOkuyucu = new BinaryReader(agAkisi);
BinaryWriter binaryYazici = new BinaryWriter(agAkisi);
string alinanMetin = binaryOkuyucu.ReadString();
MessageBox.Show(alinanMetin, "Yeni Genelge", MessageBoxButtons.OK);
binaryYazici.Write(true);
dinleyiciSoket.Stop();
Connect();
}
////////// CLIENT SIDE //////////////
private string IpAdresi(string host)
{
string address = "";
IPAddress[] addresslist = Dns.GetHostAddresses(host);
foreach (IPAddress theaddress in addresslist)
{
if (theaddress.AddressFamily == AddressFamily.InterNetwork)
{
address = theaddress.ToString();
}
}
return address;
}
bool onay;
private void button1_Click(object sender, EventArgs e)
{
//create socket connection
Socket istemciBaglantisi = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//Bağlantıyı gerçekleştir
if (istemciBaglantisi.Connected != true)
{
istemciBaglantisi.Connect(IPAddress.Parse(IpAdresi(txtHost.Text)), 10048);
}
agAkisi = new NetworkStream(istemciBaglantisi);
binaryYazici = new BinaryWriter(agAkisi);
binaryOkuyucu = new BinaryReader(agAkisi);
binaryYazici.Write(txtMesaj.Text);
onay = binaryOkuyucu.ReadBoolean();
MessageBox.Show(onay.ToString());
istemciBaglantisi.Close();
}
Take a look at object serialization. See here for examples. That should get you going in the right direction.
You can use google's protocol buffers. It is a fast and compact mechanism for serializing objects. There are two implementations on .NET: protobuf-net and protobuf.
I'd use object serialization or XmlSerialization, both available in .NET. I would not look at Google's protocol buffers, because that RPC encoding has little advantage over what's already in .NET, but it is obscure, especially in the .NET world, and especially now. I wouldn't bet on it becoming mainstream for .net devs. As a result, you will only make your code harder to maintain by using this RPC encoding.
I don't really see the need for protobufs when the apps that are interconnecting are homogeneous, and are NOT on the scale of Google's datacenters. I also don't see the need even when heterogeneity is the rule, because we already have JSON and XML. They are both readable and serviceable, where protobufs are not.
In any case .NET has what you need for this, built-in.