Еще не реализовано: открытый ключ DSA

Я пишу как сервер, так и клиентское приложение для Android. Клиент Android отправляет измерения на сервер. Для обеспечения целостности данных к каждому измерению добавляется цифровая подпись.

Поскольку мне нужно, чтобы все было совместимо с Gson, сохранение открытого ключа невозможно. Вместо этого я сохраняю факторы G, P, Q и Y.

Вот фрагмент из класса запроса:

    public PublicKey getPublicKey() {
    try {
        DSAPublicKeySpec keySpec = new DSAPublicKeySpec(publicKeyY, publicKeyP,
                                                        publicKeyQ, publicKeyG);
        KeyFactory fact = KeyFactory.getInstance("DSA");
        PublicKey pubKey = fact.generatePublic(keySpec); // A
        return pubKey;
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
}

public void setPublicKey(PublicKey publicKey) {
    try {
        KeyFactory fact = KeyFactory.getInstance("DSA");
        DSAPublicKeySpec pub = fact.getKeySpec(publicKey, DSAPublicKeySpec.class); // B
        publicKeyG = pub.getG();
        publicKeyP = pub.getP();
        publicKeyQ = pub.getQ();
        publicKeyY = pub.getY();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

Конструктор использует метод setPublicKey. Когда я создаю такой запрос на стороне клиента и отправляю его на сервер, оба приводят к исключению.

На клиенте:

 java.lang.RuntimeException: not implemented yet DSA Public Key
             y: 2f9286201b266f38d682e99814612f7d37c575d3a210de114bdf02092f4a835109f28a590cfc568bb6525d59b8275fe791f3ddf20e85df44fd2e8622289f6dbc27c73d31d1769feae19573df22a9ca8ef80a9f7230b0b4a2671cc03fdb2788b55b4e9a68a7a5a93a214cc5aa39ccb5155a13354870d45a38760a80fd34333073
  class java.security.spec.DSAPublicKeySpec
    at org.bouncycastle.jce.provider.JDKKeyFactory.engineGetKeySpec(JDKKeyFactory.java:148)
    at java.security.KeyFactory.getKeySpec(KeyFactory.java:210)

Следующая вещь в трассировке стека указывает на правило, которое я пометил как B

На сервере:

java.lang.NullPointerException
    at sun.security.provider.DSAPublicKey.<init>(DSAPublicKey.java:74)
    at sun.security.provider.DSAPublicKeyImpl.<init>(DSAPublicKeyImpl.java:46)
    at sun.security.provider.DSAKeyFactory.engineGeneratePublic(DSAKeyFactory.java:86)
    at java.security.KeyFactory.generatePublic(KeyFactory.java:304)
    at sensserve.protocol.StartSessionRequest.getPublicKey(StartSessionRequest.java:66)

Далее, указывая на правило А.

Я абсолютно не понимаю, что я сделал не так и что означают эти сообщения. Как я могу решить их? Любой, кто может сказать мне, что я делаю неправильно?

Большое спасибо.


person gleerman    schedule 10.05.2012    source источник


Ответы (1)


Вы должны иметь возможность хранить открытый ключ в кодировке Base64 и по-прежнему получать действительный JSON. Вы должны иметь возможность использовать DSAPublicKeySpec напрямую, не вызывая getKeySpec(), что, по-видимому, не реализовано в Bouncy Castle (поставщик JCE для Android). Не уверен, почему вы получаете NPE на сервере, возможно, неправильный формат. Кстати, вероятно, будет проще, если вы имеете дело с одним провайдером, поэтому вы можете использовать Bouncy Castle и на сервере.

person Nikolay Elenkov    schedule 10.05.2012
comment
Спасибо за ваш комментарий, это помогло мне обменять открытый ключ. Однако проверка по-прежнему не работает. Я думаю, что ваше последнее предложение может иметь какое-то отношение к этому. Я сделал об этом отдельную тему: stackoverflow.com/questions/10601507/ Не могли бы вы также взглянуть? - person gleerman; 15.05.2012