I've been experimenting with the BouncyCastle API for Java and slowly working my way through their "Java Cryptography - Tools and Techniques" ebook. The book contains a short section titled "A Word About Entropy" which states the following:
What the JVM is using as an entropy source will vary, on Linux for example, it is normally set to “/dev/random” which may block. Usually installing
“rng-tools” or the nearest equivalent will deal with this as it will also
expose any underlying hardware supporting RNG generation to be used for
seeding “/dev/random”. With some virtual environments hardware RNG may
never be available, in that case it is important to find other ways of making entropy available to your JVM. Ways of doing this will vary with the environment you are using.
I might be misunderstanding what this excerpt is saying, but how exactly can I make entropy available to the JVM? The book isn't very specific about this other than stating that the "Ways of doing this will vary with the environment you are using". Is there some kind of Entropy SPI that I am unaware of which can be used to make a source of entropy available to the JVM? My question isn't how to generate entropy or retrieve it from the JVM, but rather, if I already know of and have access to a reliable source of entropy (Such as a file of random bits) how can I make this source of entropy available to the JVM so that it may be used for seeding in cases where other secure sources of entropy are unavailable?
This may vary depending on the JVM vendor but as per
Avoiding JVM Delays Caused by Random Number Generation for Sun/Oracle JVM one can set securerandom.source property in $JAVA_HOME/jre/lib/security/java.security file. This allows to change the source of entropy e.g. from /dev/random to /dev/urandom.
To add more entropy one can simply write to /dev/random. As per this answer this can potentially not be secure but:
It is also possible to write to /dev/random. This allows any user to mix random data into the pool.
I don't think your quote is an accurate reflection of at least the Oracle JVM. Here is the Javadoc for the NativePRNG class that is normally chosen by default.
public final class NativePRNG extends java.security.SecureRandomSpi
Native PRNG implementation for Solaris/Linux/MacOS. It obtains seed
and random numbers by reading system files such as the special device
files /dev/random and /dev/urandom. This implementation respects the
securerandom.source Security property and java.security.egd System
property for obtaining seed material. If the file specified by the
properties does not exist, /dev/random is the default seed source.
/dev/urandom is the default source of random numbers.
On some Unix platforms, /dev/random may block until enough entropy is
available, but that may negatively impact the perceived startup time.
By selecting these sources, this implementation tries to strike a
balance between performance and security.
As you can see, /dev/urandom and not /dev/random is the default source of entropy.
Related
I have found many, many resources about Java access modifiers that explain what they are and how to use them and why to use them and when to use them. But, I have found no discussion on how they work or how much Java depends on the operating system to enforce them and if so, how much the enforcement is dependent on which operating system is used. Possibly, I am using the wrong search terms.
Basically it's 100% controlled by Java and the JVM, and the OS has nothing to do with it. There's no hardware intervention (for example) in controlling access to a private field. It's just the software running on the JVM doesn't let you (directly, you can do it with reflection) read the memory location of that field.
AFAIK, all Java objects are allocated on the heap which is just ordinary memory that can be read or written. Some parts of the JVM might actually be protect by the OS -- executable memory for example, or the stack. But Java is a unified memory system where all memory, all objects and their fields, go in the same OS "bucket" of memory, and that's the heap.
I think this is sometimes called a SISD model -- "single instruction single data," where the "single data" is just the heap. And yes I'm ignoring the SIMD instructions that Intel has because those instructions are relatively rare.
I have little to no knowledge of Java as a whole. I also tried to find that information by myself, without success though. This is why I decided to ask it here despite the negative attitude I am expecting afterwards. So here it is:
Does the JVM have access to the memory registries, or it uses(calls) the underlying system(the operation system or BIOS ) interfaces?
I am asking this question for basic knowledge of what JVM depends on.
- On the operation system?
- On the hardware platform (processor)?
- Or may be on both?
I am considering this issue, because I have a kit with processor Allwinner A20 running Linux Debian. I want to run a code (java code if possible) that manipulates the processor's GPIOs.
I have read that Java has ports to many platforms. What do they mean by platform - operation system or hardware(CPUs)?
This lack of clarity is not uncommon and dates back to the early days of Java, nearly 20 years ago now.
The term Java can refer to either of two distinct though tightly related things:
a language, object-oriented in nature, compilers for which produce not CPU-specific machine code but an abstract machine code
a program, or "runtime", that is hardware- and OS-specific, whose job it is to execute the abstract machine code on a particular hardware/OS platform combination
Since JRE was mentioned- the "JRE" artifact for a particular hardware/OS platform is largely just the second thing, while the "JDK" artifact for a particular hardware/OS platform is both things;
Java-the-language very deliberately does not have any direct facilities for utilizing OS/hardware specific resources. Everything is abstracted by classes, and while many hardware/OS objects- like Threads and Files- have abstract representations in Java-the-language's object oriented class library, many others- process IDs, for instance- do not.
Java-the-runtime is an extremely sophisticated piece of machinery that can turn abstract machine instructions produced by Java-the-language's compiler into executable code, execution of which can rival native, hand-tuned implementations in performance, at the cost of some efficiency for automated memory management- and can do so on different OS/hardware platforms from the same source code written in Java-the-language.
Although Java-the-language does not have facilities to talk directly to hardware- that is, to the interface to the hardware exposed by the operating system- Java-the-runtime has the ability to load hardware/OS specific native libraries that are authored in accordance with specific requirements and which can expose an object-oriented interface to the specific hardware/OS facility to programs written in Java-the-language.
There is of course more subtlety in this world- there are fundamental differences between the two dominant providers- Oracle, formerly Sun, which produces a toolchain for desktop and server platforms, and Google which produces a toolchain for Android-based hardware.
The same source code has some degree of compatibility between the two toolchains, though the abstract machine code produced from that source code by one toolchain is not compatible with the other.
That said, it is the case that if you have a specific piece of hardware, and you want to talk to it from Java-the-language, you need:
an operating system that runs on the hardware
a Java-the-runtime for that specific operating system/hardware platform- whether based on Oracle/Sun's work, or Google's
a native library that adheres to the expectations Java-the-runtime has, that provides a suitable interface to the hardware for Java-the-language
How can you prevent a JNA method-call from exceeding thresholds for CPU utilization, thread-counts, and memory limits?
Background:
I'm working on a safety critical application and one of the non-safety-critical features requires the use of a library written in C. The dlls have been given to me as a black-box and there's no chance that I'll get access to the source code beyond the java interface files. Is there a way to limit the CPU usage, thread-count, and memory used by the JNA code?
See ulimit and sysctl, which are applicable to your overall JVM process (or any other process, for that matter).
It's not readily possible to segment parts of your JVM which are making native accesses via JNA from those that aren't, though.
You should run some profiling while you exercise your shared library to figure out what resources it does use, so you can focus on setting limits around those (lsof or strace would be used on linux, I'm not sure of the equivalent on windows).
For most operating systems you must either call your C code from a new thread or new process. I would recommend calling it from a new process as then you can sandbox it easier and deeper. Typically on a Unix like system one switches to a new user set aside for the service and that has user resource limits on it. However, on Linux one can use user namespaces and cgroups for more dynamic and flexible sandboxing. On Microsoft Windows one typically uses Job objects for resource sandboxing but permissions based sandboxing is more complicated (a lot of Windows is easily sandboxable with access controls but the GUI and window messaging parts make things complicated and annoying).
I have been using java for long time but this question came to my mind recently and has been troubling me since.
I am aware about some conditions where platform agnosticism may be affected in java world via.
code for interaction with file system
using platform dependent libraries in the code.
Also floating point numbers
Are there any more cases where java platform agnosticism may fail?
Say a case where my file compiled on Solaris may fail to run on RedHat Linux.
Any help on the topic is appreciated.
Platform specific methods such as
Runtime.exec() is platform specific.
Anything under sun.* or com.sun.* may or may not be there, or do the same thing.
Some system properties are supposed to differ based on the system. e.g. There was one application which expected certain vendors which failed when the VM Vendor changed to Oracle. ;)
Anything which depends on System.getenv()
using native libraries
You need to be careful with paths, e.g. using \ and / between Windows and UNIX is asking for trouble. Also, newline may be tricky: Windows is CR+LF, UNIX just CR (if I recall correctly). Java does provide mechanisms to handle such issues, but naive/new developers may miss them.
Also, I believe OS file locking is different, e.g. on Windows you may be blocked/denied access for something which on UNIX you wouldn't be.
Some libraries, which are not platform dependent, use JVM defaults. For example JVM may choose a different cryptography algorithm if you request AES on two machines. In this case you should be more specific when choosing the algorithm, for instance AES/ECB/PKCS5Padding. See Java default Crypto/AES behavior.
So in general, be careful when docs says that there is some default and don't use defaults.
How can I check and detect a JVM corrupted?
How can I check that Security Manager, Byte Code Verifier and Class Loader are working correctly?
How can I check and detect a JVM corrupted? How can I check that Security Manager, Byte Code Verifier and Class Loader are working correctly?
You would do this the same way you would do for any other process. Typically, you would use a HIDS (Host Intrusion Detection System) that would detect if any changes are made to files. In your case, you would need a HIDS system that is capable of detecting changes to the filesystem, especially for the artifacts that constitute the runtime - the java executable and related shared libraries, and the runtime classes of the JRE. As long as the HIDS has been configured to detect changes to these files, you would not need any extraneous mechanisms for protecting them.
I've mostly encountered the use of Samhain and Tripwire for this purpose. There could be other HIDS systems that are also capable of this task.
You should not expect to find any mechanisms within the JVM itself that will detect if the JVM installation has been compromised, after such a mechanism itself could be compromised first, leading to a false belief that the JVM is trustworthy.