Send APDU command to card through HID OMNIKEY 5427 CK - hid

I'm trying to pass though APDUs command via HID OMNIKEY 5427 CK to operate MIFARE Card ie. Ultralight C card, on the Windows 10 x64 OS environment using WinSCard.dll. (I'm under NXP NDA and have full access t their documents)
I tried to find information online for days now. Seem like no published document for this model except the 2pages brochure.
The simple command like GetUID (FFCA000000) is OK, I can get back the actual card UID.
But for 'Authentication with Card', reference document from HID 5421 model said I should start with OpenGenericSession (FFA0000703010001), I tried that and reader always replied with 6D00h (error)
I tried send Authentication command directly '1Ah+00h' (FFA00005080100F30000641A0000) the reader also always replied with error code.
I've experience with HID 5421 model and it quite straight forward, not sure why this 5427 is unlike its sibling.
And yes, I contacted HID support. No luck. No useful information I could get from them.
If any one have idea or have 5427 software development guide please help. I'm pulling my hair for almost a week by now.

Below is a proof-of-concept java code to communicate with Ultralight-C over Generic Session using Omnikey 5321/6321:
private static final byte AF = (byte)0xAF;
protected static final byte[] PREFIX = new byte[] { 0x01, 0x00, (byte) 0xF3, 0x00, 0x00, 0x64 };
protected final CardChannel channel;
protected void openGenericSession() throws CardException {
System.out.println("OPEN GENERIC SESSION");
transmitAssert9000(new CommandAPDU(0xFF, 0xA0, 0x00, 0x07, new byte[] { 0x01, 0x00, 0x01}));
}
protected byte[] transmitRaw(byte[] data) throws CardException {
System.out.println(" => " + toHex(data));
byte[] ret = transmitAssert9000(new CommandAPDU(0xFF, 0xA0, 0x00, 0x05, ArrayUtils.addAll(PREFIX, data), 256));
if(ret.length<2) {
throw new RuntimeException();
}
if((ret[0]==0x00)&&(ret[1]==0x00)) {
// Success
ret = Arrays.copyOfRange(ret, 2, ret.length);
System.out.println(" <= " + toHex(ret));
return ret;
}
if((ret[0]==0x08)&&(ret[1]==0x04)&&(ret.length==3)) {
// ACK/NAK
switch(ret[2]) {
case 0x0A:
System.out.println(" <= ACK");
return ArrayUtils.EMPTY_BYTE_ARRAY;
default:
// Buyer beware: very simplified
System.out.println(" <= NAK");
throw new RuntimeException("NAK");
}
}
ret = Arrays.copyOfRange(ret, 2, ret.length);
System.out.println(" <= " + toHex(ret));
return ret;
}
protected static byte[] assert9000(ResponseAPDU transmit) {
if(transmit.getSW()!=0x9000) {
throw new RuntimeException("Unexpected response code");
}
return transmit.getData();
}
protected byte[] transmitAssert9000(CommandAPDU commandAPDU) throws CardException {
return assert9000(transmit(commandAPDU));
}
protected ResponseAPDU transmit(CommandAPDU commandAPDU) throws CardException {
System.out.println(" -> " + toHex(commandAPDU.getBytes()));
ResponseAPDU responseAPDU = channel.transmit(commandAPDU);
System.out.println(" <- " + toHex(responseAPDU.getBytes()));
return responseAPDU;
}
public byte[] read(int offset) throws CardException {
System.out.println("READ");
return transmitRaw(new byte[] {0x30, (byte)offset});
}
Note 1: this code uses javax.smartcardio and Apache Commons Lang.
Note 2: It has been some time I wrote this code, please validate my thoughts...
Note 3: For Ultralight-C authentication code see this companion answer.
Generic session example trace for Omnikey 6321 with Ultralight-C (single line arrows denote Generic Session APDUs and double line arrows denote Ultralight-C commands):
OPEN GENERIC SESSION
-> FFA0000703010001
<- 9000
AUTHENTICATE
=> 1A00
-> FFA00005080100F30000641A0000
<- 0000AF4BDA4E34B5D04A019000
<= AF4BDA4E34B5D04A01
=> AF6F18402E0F0E5357D854833B149FBB56
-> FFA00005170100F3000064AF6F18402E0F0E5357D854833B149FBB5600
<- 000000F0F667CCF0E140419000
<= 00F0F667CCF0E14041
READ
=> 3003
-> FFA00005080100F3000064300300
<- 0000000000000000000000000000000000009000
<= 00000000000000000000000000000000
CLOSE GENERIC SESSION
-> FFA0000703010002
<- 9000
Some additional notes:
(AFAIK) This approach works under Windows (with Omnikey drivers). It does not work under linux (even with Omnikey drivers).
Note that PC/SC version 2.02 Part 3 defines MANAGE SESSION, TRANSAPARENT EXCHANGE and SWITCH PROTOCOL commands which provide the same in a standardized way (your reader might support it instead of proprietary generic session mechanism -- HID even participated on this document).
Good luck!

Related

Write to HID with Chip Selection with .NET Console App

Hi I am writing a simple console app that needs to write bytes to MCP2210 USB to SPI Master
I found this library over here, seems to do good job with connecting the device and reading the metadata.
I am writing message to the board as below
public static byte[] Talk()
{
var device = DeviceList.Local.GetHidDevices(1240, 222).FirstOrDefault();
if (device == null)
{
Console.WriteLine($"Could not find a device with Vendor Id:1240, Product Id:222 ");
return null;
}
var reportDescriptor = device.GetReportDescriptor();
foreach (var deviceItem in reportDescriptor.DeviceItems)
{
Console.WriteLine("Opening device for 20 seconds...");
if (!device.TryOpen(out var hidStream))
{
Console.WriteLine("Failed to open device.");
continue;
}
Console.WriteLine("Opened device.");
hidStream.ReadTimeout = Timeout.Infinite;
hidStream.Write(new byte[3] {60, 00, 00});
}
Not sure If I am writing it correctly.
While writing I need to do a chip selection as displayed in this other terminal
Any help is greatly appreciated
Here is the MC I am using https://www.microchip.com/wwwproducts/en/MCP2210
I do not see a closing of your stream. This may cause your data to not even being sent (at least not in time).
Consider using blocks with streams.
But with out parameters not possible.

Netty server memory usage keep increasing and eventually crashes with io.netty.util.internal.OutOfDirectMemoryError

Below is the code of my netty server. It is configured to release reference count on channelRead i.e wont be processing anything just drop the incoming data.
Client is also netty based. Which starts 16 parallel connections with server and start sending data on each channel.
However as soon as program starts, memory usage keep increasing and eventually it crashes with following exception.
08:41:15.789 [nioEventLoopGroup-3-1] WARN i.n.channel.DefaultChannelPipeline - An exceptionCaught() event was fired, and it reached a
t the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception.
io.netty.util.internal.OutOfDirectMemoryError: failed to allocate 100663296 byte(s) of direct memory (used: 3602907136, max: 369885184
0)
at io.netty.util.internal.PlatformDependent.incrementMemoryCounter(PlatformDependent.java:640) ~[sosagent.jar:1.0-SNAPSHOT]
at io.netty.util.internal.PlatformDependent.allocateDirectNoCleaner(PlatformDependent.java:594) ~[sosagent.jar:1.0-SNAPSHOT]
at io.netty.buffer.PoolArena$DirectArena.allocateDirect(PoolArena.java:764) ~[sosagent.jar:1.0-SNAPSHOT]
at io.netty.buffer.PoolArena$DirectArena.newUnpooledChunk(PoolArena.java:754) ~[sosagent.jar:1.0-SNAPSHOT]
at io.netty.buffer.PoolArena.allocateHuge(PoolArena.java:260) ~[sosagent.jar:1.0-SNAPSHOT]
at io.netty.buffer.PoolArena.allocate(PoolArena.java:231) ~[sosagent.jar:1.0-SNAPSHOT]
at io.netty.buffer.PoolArena.reallocate(PoolArena.java:397) ~[sosagent.jar:1.0-SNAPSHOT]
at io.netty.buffer.PooledByteBuf.capacity(PooledByteBuf.java:118) ~[sosagent.jar:1.0-SNAPSHOT]
at io.netty.buffer.AbstractByteBuf.ensureWritable0(AbstractByteBuf.java:285) ~[sosagent.jar:1.0-SNAPSHOT]
at io.netty.buffer.AbstractByteBuf.ensureWritable(AbstractByteBuf.java:265) ~[sosagent.jar:1.0-SNAPSHOT]
at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:1079) ~[sosagent.jar:1.0-SNAPSHOT]
at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:1072) ~[sosagent.jar:1.0-SNAPSHOT]
at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:1062) ~[sosagent.jar:1.0-SNAPSHOT]
at io.netty.handler.codec.ByteToMessageDecoder$1.cumulate(ByteToMessageDecoder.java:92) ~[sosagent.jar:1.0-SNAPSHOT]
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:263) ~[sosagent.jar:1.0-SNAPSHOT]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [sosagent.jar:1.0-
SNAPSHOT]
NettyServerHandler
public class AgentServerHandler extends ChannelInboundHandlerAdapter implements RequestListener {
private Buffer buffer;
private AgentToHost endHostHandler;
private String remoteAgentIP;
private int remoteAgentPort;
private ChannelHandlerContext context;
private float totalBytes;
private long startTime;
boolean called;
#Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
InetSocketAddress socketAddress = (InetSocketAddress) ctx.channel().remoteAddress();
log.debug("New agent-side connection from agent {} at Port {}",
socketAddress.getHostName(),
socketAddress.getPort());
this.context = ctx;
remoteAgentIP = socketAddress.getHostName();
remoteAgentPort = socketAddress.getPort();
requestListenerInitiator.addRequestListener(this);
if (this == null ) log.info("EHy nULLL ");
// Utils.router.getContext().getAttributes().put("agent-callback", requestListenerInitiator);
StatCollector.getStatCollector().connectionAdded();
startTime = System.currentTimeMillis();
}
private boolean isMineChannel(RequestTemplateWrapper request, AgentServerHandler handler) {
// if (handler == null) log.info("nULLLL"); else log.info("not null");
return request.getPorts().contains(((InetSocketAddress) handler.context.channel().remoteAddress()).getPort());
}
/* Whenever AgentServer receives new port request from AgentClient.
This method will be called and all the open channels
will be notified. */
#Override
public void newIncomingRequest(RequestTemplateWrapper request) {
endHostHandler = getHostHandler(request);
if (isMineChannel(request, this)) {
endHostHandler.addChannel(this.context.channel());
log.debug("Channel added for Client {}:{} Agent Port {}",
request.getRequest().getClientIP(),
request.getRequest().getClientPort(),
(((InetSocketAddress) this.context.channel().remoteAddress())).getPort());
this.buffer = bufferManager.addBuffer(request, endHostHandler);
}
endHostHandler.setBuffer(buffer);
}
#Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
ReferenceCountUtil.release(msg);
totalBytes += ((ByteBuf) msg).capacity();
}
}
Bootstrap
private boolean startSocket(int port) {
group = new NioEventLoopGroup();
AgentTrafficShaping ats = new AgentTrafficShaping(group, 5000);
ats.setStatListener(this);
try {
ServerBootstrap b = new ServerBootstrap();
b.group(group)
.channel(NioServerSocketChannel.class)
.localAddress(new InetSocketAddress(port))
.childHandler(new ChannelInitializer() {
#Override
protected void initChannel(Channel channel) throws Exception {
channel.pipeline()
.addLast("agent-traffic-shapping", ats)
.addLast("lengthdecorder", new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4))
// .addLast("bytesDecoder", new ByteArrayDecoder())
.addLast(new AgentServerHandler())
.addLast("4blength", new LengthFieldPrepender(4))
// .addLast("bytesEncoder", new ByteArrayEncoder())
;
}
}
);
ChannelFuture f = b.bind().sync();
log.info("Started agent-side server at Port {}", port);
return true;
// Need to do socket closing handling. close all the remaining open sockets
//System.out.println(EchoServer.class.getName() + " started and listen on " + f.channel().localAddress());
//f.channel().closeFuture().sync();
} catch (InterruptedException e) {
log.error("Error starting agent-side server");
e.printStackTrace();
return false;
} finally {
//group.shutdownGracefully().sync();
}
}
What could be possible cause here. I know netty uses reference count to keep track of Buffers. I am just releasing the reference as soon as I get a message so that shouldn't be problem !
There might be different reasons for OOM exception. One reason readily comes to my mind is is setting AUTO_READ option on the channel. The default value is true.
you can get more information about this in stack overflow posts here and here
If setting AUTO_READ option doesn't help, netty provides an option to check if any message to ChannelHandler is not released. Please set -Dio.netty.leakDetectionLevel=ADVANCED JVM option in the system properties.
This happens because the client is writing faster than what the server can process. This ends up filling up the client buffer (memory) and eventual crash. The solution is to adjust the client send rate based on the server. One way to achieve this is that the server periodically reports the reading rate to the client and the client adjusts the write speed based on that.

PDF File size of 50kb increases dramatically up to 9mb after signing it with previously using Itext Java Application

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.

Test Event expiration in Drools Fusion CEP

Ciao, I have tested in several ways, but I'm still unable to test and verify the Event expiration mechanism in Drools Fusion, so I'm looking for some little guidance, please?
I've read the manual and I'm interested in this feature:
In other words, one an event is inserted into the working memory, it is possible for the engine to find out when an event can no longer match other facts and automatically retract it, releasing its associated resources.
I'm using the Drools IDE in Eclipse, 5.4.0.Final and I modified the template code created by the "New Drools Project" wizard to test and verify for Event expiration.
The code below. The way I understood to make the "lifecycle" to work correctly is that:
You must setup the KBase in STREAM mode - check
You must Insert the Events in temporal order - check
You must define temporal constraints between Events - check in my case is last Message()
However, when I inspect the EventFactHandle at the end, none of the Event() has expired.
Thanks for your help.
Java:
public class DroolsTest {
public static final void main(String[] args) {
try {
KnowledgeBase kbase = readKnowledgeBase();
// I do want the pseudo clock
KnowledgeSessionConfiguration conf = KnowledgeBaseFactory.newKnowledgeSessionConfiguration();
conf.setOption(ClockTypeOption.get("pseudo"));
StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession(conf, null);
SessionPseudoClock clock = ksession.getSessionClock();
KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test");
// Insert of 2 Event:
Message message = new Message();
message.setMessage("Message 1");
message.setStatus(Message.HELLO);
ksession.insert(message);
ksession.fireAllRules();
clock.advanceTime(1, TimeUnit.DAYS);
Message message2 = new Message();
message2.setMessage("Message 2");
message2.setStatus(Message.HELLO);
ksession.insert(message2);
ksession.fireAllRules();
clock.advanceTime(1, TimeUnit.DAYS);
ksession.fireAllRules();
// Now I do check what I have in the working memory and if EventFactHandle if it's expired or not:
for (FactHandle f : ksession.getFactHandles()) {
if (f instanceof EventFactHandle) {
System.out.println(((EventFactHandle)f)+" "+((EventFactHandle)f).isExpired());
} else {
System.out.println("not an Event: "+f);
}
}
logger.close();
} catch (Throwable t) {
t.printStackTrace();
}
}
private static KnowledgeBase readKnowledgeBase() throws Exception {
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(ResourceFactory.newClassPathResource("Sample.drl"), ResourceType.DRL);
KnowledgeBuilderErrors errors = kbuilder.getErrors();
if (errors.size() > 0) {
for (KnowledgeBuilderError error: errors) {
System.err.println(error);
}
throw new IllegalArgumentException("Could not parse knowledge.");
}
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
// following 2 lines is the template code modified for STREAM configuration
KnowledgeBaseConfiguration config = KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
config.setOption( EventProcessingOption.STREAM );
return kbase;
}
/*
* This is OK from template, as from the doc:
* By default, the timestamp for a given event is read from the Session Clock and assigned to the event at the time the event is inserted into the working memory.
*/
public static class Message {
public static final int HELLO = 0;
public static final int GOODBYE = 1;
private String message;
private int status;
public String getMessage() {
return this.message;
}
public void setMessage(String message) {
this.message = message;
}
public int getStatus() {
return this.status;
}
public void setStatus(int status) {
this.status = status;
}
}
}
Drools:
package com.sample
import com.sample.DroolsTest.Message;
declare Message
#role(event)
end
declare window LastMessageWindow
Message() over window:length(1)
end
rule "Hello World"
when
accumulate( $m : Message(status==Message.HELLO) from window LastMessageWindow,
$messages : collectList( $m ) )
then
System.out.println( ((Message)$messages.get(0)).getMessage() );
end
Please note: even if I add expiration of 1second to the Message event, by
#expires(1s)
I still don't get the expected result that the very first Message event inserted, I would have expected is now expired? Thanks for your help.
Found solution! Obviously it was me being stupid and not realizing I was using Drools 5.4.0.Final while still referring to old documentation of 5.2.0.Final. In the updated documentation for Drools Fusion 5.4.0.Final, this box is added for 2.6.2. Sliding Length Windows:
Please note that length based windows do not define temporal constraints for event expiration from the session, and the engine will not consider them. If events have no other rules defining temporal constraints and no explicit expiration policy, the engine will keep them in the session indefinitely.
Therefore the 3rd requirement I originally enlisted of "You must define temporal constraints between Events" is obviously NOT met because I now understand Sliding Length Window in Drools 5.4.0.Final:
Message() over window:length(1)
are indeed NOT a definition of a temporal constraints for event expiration from the session.
Updating this answer hopefully somebody will find it helpful. Also, just so for your know, me being stupid actually for relying on googling in order to reach the doc, and sometimes you don't get redirected to the current release documentation, so it seems...

Is it possible to decrypt my XMPP server traffic using private key?

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.