I want B to be run only by the private
method A#getSensitiveData()
that uses or does some processing on sensitive data (example: cryptographic keys, national id, whatever).
public final class A{ private transient final B sensitiveHolder; //set at Constructor public A(B sensitiveHolder){ this.sensitiveHolder = sensitiveHolder; } private final byte[] getSensitiveData(){ return sensitiveHolder.getSensitiveData(); } } public final class B{ private transient final byte[] sensitiveData;//encrypt and set at Constructor public final byte[] getSensitiveData(){ //check if it is run by A#getSensitiveData(); if it is, decrypt by DEK and give plaintext. } }
Please take into account that the code would be obfuscated, so please refrain from putting in any package names as String
.
What must I write with SecurityManager#checkPrivilege()
and AccessController.doPrivileged()
before I can achieve such an effect?
EDIT: Obviously this is different because the so called "answer" does not contain any CODE. WORKING CODE is worth infinitely more than "oh, just do this and that".
2 Answers
Answers 1
You could do something like this:
private boolean verify(final StackTraceElement e[]) { boolean doNext = false; for (final StackTraceElement s : e) { if (doNext && s.getClassName().equals("A") && s.getMethodName().equals("getSensitiveData")) return true; doNext = s.getMethodName().equals("getStackTrace"); } return false; }
And to call the method:
public final byte[] getSensitiveData(StackTraceElement e[]){ if (verify(e)) { // Do something good } }
In your A
class call your B
class like this:
return sensitiveHolder.getSensitiveData(Thread.currentThread().getStackTrace());
I don't know if this is what you need or it is near that. You could play around the values in the equals
section of the if
. I got and modified the example from this site.
Answers 2
If you're able to use JDK 9+, which introduces StackWalker
, this sort of thing might work for you. This technique seems to supersede use of sun.reflect.Reflection#getCallerClass(int)
. (I hope you weren't counting on a SecurityManager-related answer.)
package asdf; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import java.util.EnumSet; import java.util.List; import java.util.stream.Collectors; public class Asdf { @Test public void what() { get(); } void get() { StackWalker.StackFrame stackFrame = StackWalker.getInstance(EnumSet.of(StackWalker.Option.RETAIN_CLASS_REFERENCE)) .walk(stream -> { List<StackWalker.StackFrame> stackFrames = stream.collect(Collectors.toList()); return stackFrames.get(1); }); Assertions.assertEquals(Asdf.class, stackFrame.getDeclaringClass()); Assertions.assertEquals("what", stackFrame.getMethodName()); Assertions.assertEquals(0, stackFrame.getMethodType().parameterCount()); } }
0 comments:
Post a Comment