I formerly signed jar files using a locally installed keystore as part of an automated build. I'm now faced with having to use a hardware-based device, due to recent changes to minimal code signing requirements, and while I've figured out how to do it, I'm seeing extreme slow-downs.
Just as one example, a jar file with 180 classes that I could formerly sign in about half a second is now taking about 30 seconds. As it's going, I see my token device's access light flashing a few times a second, presumably once for each class in the jar file.
Is there any way to speed this up, e.g. some way to reduce the token accesses to a single access for the entire jar file?
It was not an answer, but it is too long for a comment:
If your supposition of an access to the token for any file is correct, then it would mean the hash of the files is also being calculated in the device, not only the signature.
Does your PKCS11 device have a logging option that could show which pkcs11 calls are the device receiving (hash operations are called C_Digest in PKCS11) to confirm?
Maybe with the option mentioned in java keytool with opensc pkcs#11 provider only works with debug option enabled (I haven't tried it)
Since I don't know if there's any way to tell jarsigner to hash by software and to sign by hardware, if you can't find a better answer, maybe you can write your own provider: ( http://docs.oracle.com/javase/7/docs/technotes/guides/security/crypto/HowToImplAProvider.html ) :
implementing a software hash (MessageDigestSpi, just forwarding the call to the default software java provider)
and a device signature (SignatureSpi, just forwarding the call to the PKCS11 provider configured in java ). I think it was Signature signature = Signature.getInstance("SHA1withRSA", "SunPKCS11") and so on. And analog for KeyStoreSpi.
And then call jarsigner with your provider as parameter.
Try adding -sigalg SHA512withRSA to your jarsigner options.
For further information, check my answer to a related question
Related
Suppose I have an an apk that I want to reverse engineer but there are some small problems regarding this. For instance if the application uses Google siging mechanism to signin into the app then I would not be able to signin after modifying the apk!
There are also couple of other reasons that why not to modify an apk with resigning it with custom keystore...!
Is it possible?
Or is there any other problem to tackle this?
It is not possible1 to modify an APK without invalidating the signature. That is the whole point of the signature.
However, the APK signature and Google's Sign-in service are different things. "Signing" and "sign-in" are different words with different meanings. From a theoretical standpoint (at least) an APK that has been modified should still be able to successfully use Google Sign-in.
Here are some background links on APK digital signatures and how they work:
Wikipedia: Digital signatures
APK Signature Scheme v2
APK Signature Scheme v3
1 - At least not currently. If someone manages to break the "crypto" that is used to implement the signature, then all bets are off. But we are probably OK for a few years ...
[UPDATE] Oracle just revised the crypto roadmap (https://www.java.com/en/jre-jdk-cryptoroadmap.html), they will not deprecate SHA-1 for codesigning: 2017-03-14 Target date changed from 2017-04-18 to 2017-07-18. Narrowed scope from all SHA-1 usage: only TLS will be affected, *code signing will not not be affected at this time*.
This does not affect, in any way, the fine answer I received below, as it will apply, no doubt, in the future.
--
Original post:
Attempting to run our Webstart-deployed Java application on JRE 9 ea 153, I get the following popup:
Looking further at details, I see that the certificate will still be valid for a while:
, therefore, I am wondering if deprecating SHA1 is the reason?
This certainly does sound like a policy in line with (others' in the industry), but the message doesn't really sound neophyte-friendly (especially if it is meant to face end-users), so I am left wondering.
I looked for a roadmap. This is what I found, but I'm not sure whether I'm interpreting correctly this paragraph correctly:
Disable SHA-1 in certificate chains anchored by roots included by default in Oracle's JDK; local or enterprise CAs are not affected. Signed code that is timestamped before 2017-01-01 is not affected.
as the reason for the failure above. I would very much appreciate a confirmation.
FWIW, our certificate is issued by a CA, which I presume is different from an "enterprise" CA.
Thank you.
If that signed Jar is meant to be used by end-users there is no way a package that was SHA1 signed in 2017 is going to work.
Phasing out SHA1 was announced a long time ago.
Only way would be to install a local CA or something, but that is not going to happen on end-user machines (neither should it).
To sign a Jar for your end-users you need a new valid SHA-256 Cert from your CA, and re-sign any Jar that was signed with the old one AFTER 31.12.2016.
Your cert would have expired in a few month anyway.
Whether you have to dualsign your jars depends on the oldest JVM version you are targeting. As far as i understand it anything >=1.4.2 supports SHA-256. If you want to target even older Versions (hell when i started programming java 1.5 was already considered OLD) you would need something like dual-signing. More Information can be found here and here
"How to dual sign a jar" is probably a new topic because it is hardly related to this question i think.
I have a java web start app that extracts a dll from itself to a temp file, and loads it via System.load("full\path\to\dll").
That completes successfully. However, when I try to invoke the native methods in that dll, I get an UnsatisfiedLinkError with the name of the method.
This is a Windows 7 box, 32 bit 1.7.0_45 (and _51) jre's. This same code works everywhere else except for some computers for 1 customer.
Supposedly the accounts have no local admin permissions (that's normal) and are running Microsoft Security Center Endpoint Protection. Is there some conflict between MS EPP and java's LoadLibrary calls? My google-fu couldn't find it if there is. Or what else could explain this problem?
At first the dll wasn't signed (it's never had to be before), but I tried signing it with our code signing cert to see if that had anything to do with it, but no help.
First of all just put the library file into the application
directory.(ie App Path) Then use System.load(dll_name.dll).It will
surely success. Please check the OS you are using.
For Windows :- Library extension is ".dll"
For Linux :- Library extension is ".so"
So the ".dll" in Linux will give the UnSatisfiedLinkError(Vice versa).
Then also check for the processor Architecture like.
x86
x64
This is a bit of a late followup, but the solution to the problem related to AppSense. It was silently interfering with the load library call because the DLL was being extracted to a temp directory and that violated their policy. The effect was that the library loaded but appeared empty.
We had to sign the dll with our code signing certificate (which the jar's were already signed with), and the customer's AppSense team had to add a rule to allow our signed DLLs to be loaded.
It was a maddening problem. Hopefully this followup helps someone else.
I have a signed Java applet, and the certificate just expired. I have a new certificate, but I'm not sure that I can find the original, unsigned applet jar file. Is there any way that I can take the signed jar and replace the old certificate with a new one? Thanks.
You can't wrap it.
However, you should be able to simply re-sign the JAR with a different certificate. Signing a JAR doesn't encrypt it in anyway. It just adds stuff to the manifest section.
This is not a security issue. The re-signed certificate is different to the original one, the end-user has to accept it all over again. (I don't think you can avoid that ... because it would be a security issue!)
Anyway, the simple approach is to just try re-signing the signed applet JAR, and see whether it works, and how it behaves when you try to run it as a user.
To solve a similar situation I deleted all signature files under META-INF/*.SF and META-INF/*.RSA and signed it again.
META-INF/MANIFEST.MF now contains both the old (unused) lines with SHA-1 hash and the new SHA-256 ones; the remaining old ones don't seem to be a problem: jarsigner -verify -verbose reports everything's OK with the new signature.
I have developed an applet. But when my browser fetches it from the webserver it pops a security warring. I don't want this message to come. Meaning applet should run without the end users permession. How can I do that? Do I need to get my applet signed? If yes, from where can i get it signed? What's the cost of geting it signed?
Your description might relate to a number of problems, such as the code trying to do things which require trust. That does not sound like the case in this instance. If your unsigned code tried to do things that required trust, it would not prompt the user at start-up, but either prompt them when the trusted action is attempted (e.g. for cross site access in later JREs) or just fail with an AccessControlException or similar.
It could be that your applet uses multiple Jars and has run into the mixed code restrictions introduced in Java 1.6.0_20. But the symptoms do not sound quite right for that either.
Is your applet publicly available? What is the URL where I/we can visit it?
As an aside, if your applet tries to break out of the security sand-box, it must be trusted. That means the code must be digitally signed, and OK'd by the end user at the prompt. There is no way around it.
But it does not require a code signing certificate issued from a CA. You can roll your own code signing certificate using the tools of the SDK. I have a few small demos. of code projects that compile and build code before signing it.
You need to get yourself a code-signing certificate. Probably by some "well-known" CA if you want to avoid all warnings. The certificate itself costs money, but once you have it, you can use it to sign as many applets as you want (you do the signing yourself).