Czy używanie odbicia do szorowania String
powoduje, że używanie String
jest tak bezpieczne, jak używanie haseł pod char[]
?Bezpieczne używanie ciągu znaków do haseł za pomocą odbicia w celu wyszorowania zawartości przed odbiorem śmieci.
Z punktu widzenia bezpieczeństwa ogólnie uważa się, że najlepszą praktyką jest używanie char[]
do przechowywania/przekazywania haseł, ponieważ można wyzerować zawartość tak szybko jak to możliwe w kodzie, co może znacznie wydać się zanim garbage collector go wyczyści i pamięć jest ponownie wykorzystywana (usuwając cały ślad), ograniczając okno czasu na atak pamięci.
Jednak char[]
nie jest tak wygodne jak String
, więc byłoby przydatne, jeśli ktoś może „zarośla” a String
w razie potrzeby, dzięki czemu String
jako bezpieczne jak char[]
.
Poniżej znajduje się metoda, która używa odbicia, aby wyzerować pola String
.
Czy ta metoda jest "OK", i czy osiąga ona cel polegający na tym, aby String
był tak bezpieczny jak char[]
dla haseł?
public static void scrub(String str) throws NoSuchFieldException, IllegalAccessException {
Field valueField = String.class.getDeclaredField("value");
Field offsetField = String.class.getDeclaredField("offset");
Field countField = String.class.getDeclaredField("count");
Field hashField = String.class.getDeclaredField("hash");
valueField.setAccessible(true);
offsetField.setAccessible(true);
countField.setAccessible(true);
hashField.setAccessible(true);
char[] value = (char[]) valueField.get(str);
// overwrite the relevant array contents with null chars
Arrays.fill(value, offsetField.getInt(str), countField.getInt(str), '\0');
countField.set(str, 0); // scrub password length too
hashField.set(str, 0); // the hash could be used to crack a password
valueField.setAccessible(false);
offsetField.setAccessible(false);
countField.setAccessible(false);
hashField.setAccessible(false);
}
Oto prosty test:
String str = "password";
scrub(str);
System.out.println('"' + str + '"');
wyjściowa:
""
Uwaga: Można założyć, że hasła nie są String
stałe, a więc wywołanie tej metody nie będzie mieć niekorzystny wpływ na internowane łańcuchy.
Poza tym, metoda oparta na zasadzie prostoty jest dość "surowa". Gdybym go używał, nie zadeklarowałbym wyjątków (spróbuj/złap/zignoruj) i powtarzającego się kodu refaktora.
Wydaje się, że zeruje znaki, ale czy nie jest to całkowicie zależne od implementacji maszyny JVM? – fge
węszenie pamięci? to jest atak fantasy. dlaczego nie martwić się o coś bardziej realistycznego, np. NSA szpiegującego twój ruch sieciowy. – ZhongYu
Krzyczy "niezdefiniowane zachowanie" u mnie. Powodzenia ze smokami, velociraptorami i czarnymi dziurami :) – CodesInChaos