ESAPI Symmetric Encryption using JavaEncryptor - java

I am testing basic stuff in ESAPI, and I ran across this symmetric encryption tutorial and copied and pasted the code, (along with importing the ESAPI 2.1.0 jar file, ESAPI.properties and validation.properties in the 'src' directory in Eclipse)
Modified code from the tutorial:
import org.owasp.esapi.crypto.CipherText;
import org.owasp.esapi.crypto.PlainText;
import org.owasp.esapi.errors.EncryptionException;
import org.owasp.esapi.reference.crypto.JavaEncryptor;
public class ESAPIsymEncTester {
public static void main(String[] args) throws EncryptionException{
String myplaintext = "My plaintext";
CipherText ciphertext =
JavaEncryptor.getInstance().encrypt( new PlainText(myplaintext) );
PlainText recoveredPlaintext = JavaEncryptor.getInstance().decrypt(ciphertext);
assert myplaintext.equals( recoveredPlaintext.toString() );
System.out.println("recovered plaintext: " + recoveredPlaintext.toString());
}
}
However, when I run this in Eclipse Luna using Java 1.8, I get this stack trace:
Exception in thread "main" org.owasp.esapi.errors.EncryptionException: Encryption failure: Invalid key exception.
at org.owasp.esapi.reference.crypto.JavaEncryptor.encrypt(JavaEncryptor.java:526)
at org.owasp.esapi.reference.crypto.JavaEncryptor.encrypt(JavaEncryptor.java:338)
at com.fate.engine.test.ESAPIsymEncTester.main(ESAPIsymEncTester.java:15)
Caused by: java.security.InvalidKeyException: Invalid AES key length: 96 bytes
at com.sun.crypto.provider.AESCipher.engineGetKeySize(AESCipher.java:495)
at javax.crypto.Cipher.passCryptoPermCheck(Cipher.java:1062)
at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1033)
at javax.crypto.Cipher.init(Cipher.java:1367)
at javax.crypto.Cipher.init(Cipher.java:1301)
at org.owasp.esapi.reference.crypto.JavaEncryptor.encrypt(JavaEncryptor.java:504)
... 2 more
I am not sure if this is a bug in the JavaEncryptor.java code, or if I am pulling something that I misconfigured from the ESAPI.properties file.
I replaced the master key and salt by running the JavaEncryptor and copy/pasting the resultant key/salt.
If it is a bug, I will email the ESAPI guys to get clarification on how I can fix it, since I looked through the JavaEncryptor code and am not entirely clear where all of the pieces are coming from.
Encryptor.MasterKey=WppLubGgsc/p6HhvcPf2LA==
Encryptor.MasterSalt=YokRN9mjMUTZspEbzBY90NA6EC8=
Encryptor.PreferredJCEProvider=
Encryptor.EncryptionAlgorithm=AES
Encryptor.CipherTransformation=AES/CBC/PKCS5Padding
Encryptor.cipher_modes.combined_modes=GCM,CCM,IAPM,EAX,OCB,CWC
Encryptor.cipher_modes.additional_allowed=CBC
Encryptor.EncryptionKeyLength=128
Encryptor.ChooseIVMethod=random
Encryptor.fixedIV=0x000102030405060708090a0b0c0d0e0f
Encryptor.CipherText.useMAC=true
Encryptor.PlainText.overwrite=true
Encryptor.HashAlgorithm=SHA-512 *****
Encryptor.HashIterations=1024
Encryptor.DigitalSignatureAlgorithm=SHA1withDSA
Encryptor.DigitalSignatureKeyLength=1024
Encryptor.RandomAlgorithm=SHA1PRNG
Encryptor.CharacterEncoding=UTF-8
Encryptor.KDF.PRF=HmacSHA1 *****

You forgot to place the most important part of your log into the question:
Dec 11, 2015 8:05:24 AM org.owasp.esapi.reference.JavaLogFactory$JavaLogger log
WARNING: [SECURITY FAILURE Anonymous:null#unknown -> /JavaEncryptor] Encryption key length mismatch. ESAPI.EncryptionKeyLength is 128 bits, but length of actual encryption key is 24 bits. Did you remember to regenerate your master key (if that is what you are using)???
This is a clue that there is something here that the library expects you to do.
It seems to me that you probably have the default encryptor properties set like this in esapi.properties:
Encryptor.MasterKey=owasp1
Encryptor.MasterSalt=testtest
The class JavaEncryptor has a main method that will generate valid properties for you. Run it in eclipse or via the command line. It will give you values to replace in esapi.properties, like this:
Dec 11, 2015 8:10:25 AM org.owasp.esapi.reference.JavaLogFactory$JavaLogger log
OFF: [SECURITY AUDIT Anonymous:null#unknown -> /SecurityProviderLoader] No Encryptor.PreferredJCEProvider specified.
SecurityConfiguration for Encryptor.EncryptionKeyLength not an integer in ESAPI.properties. Using default: 128
Generating a new secret master key
use '-print' to also show available crypto algorithms from all the security providers
SecurityConfiguration for Encryptor.EncryptionKeyLength not an integer in ESAPI.properties. Using default: 128
Copy and paste these lines into your ESAPI.properties
#==============================================================
Encryptor.MasterKey=qW0Qw+8eb1Zu1MBv5djwqA==
Encryptor.MasterSalt=b0VappFU1Hd6LjIt+TGYqQlfrdU=
#==============================================================
Once I did that, your code example runs just fine.

Here's what I'm going to suggest... grab the TEST version of ESAPI.properties from GitHub ("wget https://github.com/ESAPI/esapi-java-legacy/blob/master/src/test/resources/esapi/ESAPI.properties" should work, you use 'git' or save if from your browser), put it in place, and first use it AS-IS. If it fails, then there is a problem in you tweaked code. If it works, there was a problem in your ESAPI.properties file. Many people already suggested what to look for in terms of what might be wrong, but the differences should be minor enough that you should be able to spot them by diff'ing yours versus the TEST version in src/test/resources/esapi/ESAPI.properties. (The production version, incidentally, is under 'configuration/esapi/ESAPI.properties' and is not included with the jar because of some bug in the pom.xml which I don't know how to fix as I am not a Maven guru.)
If you have further questions, contact me at my Gmail account which you should be able to find easily enough via Google with my name and the term "OWASP". Once we figure out an answer that works for you, either you or I can post an answer back to Stack Overflow, but I don't frequent this forum enough to regularly monitor it. (Although, come to think of it, I probably do get notified of replies.)
Hope this helps,
-kevin w. wall / ESAPI crypto developer and co-project lead

Related

How to use an OnlineTSPSource with esig/dss Library?

I'm attempting to use an online timestamp authority (rfc3161) with the Digital Signature Service Java library. However, the following snippet (from their test cases, and similar to the one from their Cookbook):
String tspServer = "http://tsa.belgium.be/connect";
OnlineTSPSource otsp = new OnlineTSPSource(tspServer);
/* tried setting otsp.setDataLoader(new TimestampDataLoader());
too, as it defaults to otsp.setDataLoader(new
NativeHTTPDataLoader()); the exception happens in both cases */
byte[] digest = DSSUtils.digest(DigestAlgorithm.SHA1, "Hello world".getBytes());
TimeStampToken timeStampResponse =
otsp.getTimeStampResponse(DigestAlgorithm.SHA1, digest);
always ends with the following exception:
eu.europa.esig.dss.DSSException:
java.util.concurrent.ExecutionException: java.lang.NoSuchMethodError:
org.apache.commons.io.IOUtils.closeQuietly(Ljava/io/Closeable;)V
Already tried many different public rfc3161 servers (some listed here). Sure there's something wrong going on there, but, as a beginner, I cannot understand what is wrong (what method should be there).
If anyone could put me in the right direction to get the snippet working (or even be kind enough to comment a reliable startup guide on cades/xades/pades with Java's bouncycastle) I would be really grateful.
As stated in the comments by Marteen Bodewes and Mark Rotteveel, there was something wrong with the version of Apache Commons-IO in the classpath. The project is set using Apache Maven and there was an old Commons-IO version declared there as a dependency. In this case, it was enough to remove that declaration, so Maven could download the appropriate version that was declared as an esig/DSS dependency.
esig/DSS version was 5.4 at the time.

Why does Apache Beam 2.2 fail on writing to GCS?

I'm working with a dataflow pipeline that a coworker recently migrated to version 2.2.0. The relevant step in the pipeline, which is throwing an error, is the following:
domainOutputBucket = "gs://output/partner/20180311/raw/DomainBatch20180311_"
output.get(domainsOut)
.setCoder(StringUtf8Coder.of())
.apply("WriteDomain" + description, TextIO.write()
.to(domainOutputBucket).withSuffix(".csv") // <-- line 109
.withWritableByteChannelFactory(FileBasedSink.CompressionType.GZIP)
.withNumShards(numChunksCustom));
When this code gets compiled however, the following error and stacktrace appear:
Exception in thread "main" java.nio.file.InvalidPathException: Illegal char <:> at index 2: gs://output/partner/20180311/raw/DomainBatch20180311_
at sun.nio.fs.WindowsPathParser.normalize(WindowsPathParser.java:182)
at sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:153)
at sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:77)
at sun.nio.fs.WindowsPath.parse(WindowsPath.java:94)
at sun.nio.fs.WindowsFileSystem.getPath(WindowsFileSystem.java:255)
at java.nio.file.Paths.get(Paths.java:84)
at org.apache.beam.sdk.io.LocalFileSystem.matchNewResource(LocalFileSystem.java:196)
at org.apache.beam.sdk.io.LocalFileSystem.matchNewResource(LocalFileSystem.java:78)
at org.apache.beam.sdk.io.FileSystems.matchNewResource(FileSystems.java:544)
at org.apache.beam.sdk.io.FileBasedSink.convertToFileResourceIfPossible(FileBasedSink.java:213)
at org.apache.beam.sdk.io.TextIO$TypedWrite.to(TextIO.java:679)
at org.apache.beam.sdk.io.TextIO$Write.to(TextIO.java:997)
at com.package.output.Partner.partnerPipeline(Partner.java:109)
at com.package.output.Output.Export(Output.java:285)
at com.package.output.Output.main(Output.java:254)
Based on this information, does anyone see what the issue might be with the code I included above? If I find the answer on my own before anyone else comments, I'll be sure to update this question for future devs.
Take a look at the comemnts on Google Cloud Dataflow: Specifying TempLocation via Command Line Argument (like after number 6).
You need to ensure that the storage class is on your class path. Otherwise the system does not know how to interpret GCP filenames and attempts to find it as a local file system.

Digest calculation of signature fails on Windows, Java 1.8

The job to do:
I have got a signed SOAP request and I have to check if the signature is okay. The timestamp of the SOAP message is not of interest.
My solution so far:
I made a child class of org.apache.wss4j.dom.engine.WSSecurityEngine where in the method processSecurityHeader the check of TimestampProcessor is taken out of concern:
public class SignatureSecurityEngine extends WSSecurityEngine {
...
public WSHandlerResult processSecurityHeader(Element securityHeader, RequestData requestData) throws org.apache.wss4j.common.ext.WSSecurityException {
...
Processor p = cfg.getProcessor(el);
if (p != null) {
try {
results = p.handleToken((Element) node, requestData, wsDocInfo);
} catch (Exception e){
if (p instanceof TimestampProcessor) {
// it's okay if timestamp is too old
} else {
throw e;
}
}
}
...
In fact it's just a copy of WSSecurityEngine with the try/catch added for timestamp processor.
I older versions of wss4j and xmlsec this worked fine.
After a version upgrade of the components, I got the following strange issue:
The calculation of the signature digest fails in org.apache.jcp.xml.dsig.internal.dom.DOMReference.validate(...) if:
The programm runs on Windows (JRE)
I debug on Windows (JDK)
I debug on Linux (JDK)
BUT:
If the programm runs on Linux (JRE), everything works fine !
For both (Windows/Linux), the configuration is:
wss4j 2.1.9
xmlsec 2.0.8
Java version: 1.8.0_131 (build 1.8.0_131-b11)
Observation:
It seems that there remains a standard value ( 2jmj7l5rSw0yVb/vlWAYkK/YBwk= ) for the calculated digest.
Any idea?
Additional facts (2017-06-13):
After Maartens remark I (re)wrote some of the classes (in fact copy & paste) and added some System.out.println to have "debug information" at runtime. Really an odd old style and ugly thing...
But the result was quite interesting!
The stream for MessageDigest was never set. So this explains the 2jmj7l5rSw0yVb/vlWAYkK/YBwk= which is the digest for an empty string with SHA-1 (thanks Maarten!)
I managed then to fix - so the stream is now set in my copied "debug"-classes.
Result: If I debug now with my IDE, the calculation functions!
But: If I run in runtime the check fails :-((( Reason: The calculated value is not equal to the expected.
Further observations showed: ev. the wrong calculation depends on the length of the data the digest has to be calculated for (!?!?!?).
Let's have a look at my log:
*** Digest for Timestamp
VGDOMReference.validate -> transform:
Expected digest: LxfIdEUVsbyLaevptByfIf2L0PA=
Actual digest: LxfIdEUVsbyLaevptByfIf2L0PA=
Reference[#Timestamp-31b20235-a1e2-4ed0-9658-67611572108e]
*** Digest for Body
Expected digest: Yv+zLpkog+xzAdMlSjoIaZntZLs=
Actual digest: sj2Gb0GEyjWuxoCmnBzDY266aG8=
Reference[#Body-c9761a98-46bb-4175-8f8b-bfa9b5c75509]
As you can see the calculation for timestamp is correct. But the one for the body is wrong.
Perhaps some stream buffer that is not entirely written?
After some tests it turned out that there was an additional encoding problem... :-(((
The original signed files are in UTF-8, but as Windows uses ISO-xyz_whatever it did not match.
First fix is to put the encoding of JVM in the script that is calling the jar, so:
java -Dfile.encoding=UTF8 <programm>.jar

How to find keylength of SSH RSA keys using java

I am using JSCH API to find length of RSA SSH keys .
I use the following code to do that:
KeyPairRSA KPR = (KeyPairRSA) KeyPairRSA.load(jsch, keypath);
System.out.println("size " +KPR.getKeySize());
This returns me always length 1024 .I think its bug with API itself.
Can anyone please tell me how to find length of RSA/DSA SSH keys?
Thanks a lot in advance.
I'm the author of JSch.
It is a bug or the incompleteness of KeyPair* classes.
They had been just introduced for the key-pair generation purposes.
But, in our internal development version, KeyPair* classes have been overhauled, and
that method has worked well.
# This is off-topic, but we have added the support for Putty's private key format, as a bonus! :-)
Anyway, the fix will be available in the next release, and if you can't wait for it,
replace KeyPairRSA#getKeySize() with the following,
public int getKeySize(){
return (new java.math.BigInteger(n_array)).bitLength();
}

Using Inline::Java in perl with threads

I am writing a trading program in perl with the newest Finance::InteractiveBrokers::TWS
module. I kick off a command line interface in a separate thread at the
beginning of my program but then when I try to create a tws object, my program
exits with this message:
As of Inline v0.30, use of the Inline::Config module is no longer supported or
allowed. If Inline::Config exists on your system, it can be removed. See the
Inline documentation for information on how to configure Inline. (You should
find it much more straightforward than Inline::Config :-)
I have the newest versions of Inline and Inline::Java. I looked at TWS.pm and it doesn't seem to be using Inline::Config. I set 'SHARED_JVM => 1' in the 'use Inline()' and 'Inline->bind()' calls in TWS.pm but that did not resolve the issue...
My Code:
use Finance::InteractiveBrokers::TWS;
use threads;
use threads::shared;
our $callback;
our $tws;
my $interface = UserInterface->new();
share($interface);
my $t = threads->create(sub{$interface->runUI()});
$callback= TWScallback->new();
$tws = Finance::InteractiveBrokers::TWS->new($manager); #This is where the program fails
So is Inline::Config installed on your system or not? A cursory inspection of the code is not sufficient to tell whether Perl is loading a module or not. There are too many esoteric ways (some intentional and some otherwise) to load a package or otherwise populate a namespace.
The error message in question comes from this line of code in Inline.pm:
croak M14_usage_Config() if %main::Inline::Config::;
so something in your program is populating the Inline::Config namespace. You should do what the program instructs you to do: find out where Inline/Config.pm is installed on your system (somewhere in your #INC path) and delete it.

Categories