Чтение открытого ключа PKCS # 1 или SPKI в Java без библиотек

MongoDB не разрешает объединения, но вы можете использовать плагины для его обработки. Проверьте плагин mongo-join. Это лучшее, и я уже использовал его. Вы можете установить его с помощью npm прямо следующим образом npm install mongo-join. Вы можете проверить полную документацию с примерами .

(++) действительно полезный инструмент, когда нам нужно объединить (N) коллекции

(- ), мы можем применять условия только на верхнем уровне запроса

Пример

var Join = require('mongo-join').Join, mongodb = require('mongodb'), Db = mongodb.Db, Server = mongodb.Server;
db.open(function (err, Database) {
    Database.collection('Appoint', function (err, Appoints) {

        /* we can put conditions just on the top level */
        Appoints.find({_id_Doctor: id_doctor ,full_date :{ $gte: start_date },
            full_date :{ $lte: end_date }}, function (err, cursor) {
            var join = new Join(Database).on({
                field: '_id_Doctor', // <- field in Appoints document
                to: '_id',         // <- field in User doc. treated as ObjectID automatically.
                from: 'User'  // <- collection name for User doc
            }).on({
                field: '_id_Patient', // <- field in Appoints doc
                to: '_id',         // <- field in User doc. treated as ObjectID automatically.
                from: 'User'  // <- collection name for User doc
            })
            join.toArray(cursor, function (err, joinedDocs) {

                /* do what ever you want here */
                /* you can fetch the table and apply your own conditions */
                .....
                .....
                .....


                resp.status(200);
                resp.json({
                    "status": 200,
                    "message": "success",
                    "Appoints_Range": joinedDocs,


                });
                return resp;


            });

    });

1
задан CJxD 17 January 2019 в 14:56
поделиться

1 ответ

Следующий код превращает открытый ключ, закодированный в PKCS # 1, в открытый ключ, закодированный в SubjectPublicKeyInfo, который является кодировкой открытого ключа, принятой RSA KeyFactory с использованием X509EncodedKeySpec, поскольку SubjectPublicKeyInfo определено в спецификациях X.509.

По сути, это низкоуровневая схема кодирования DER, которая

  1. оборачивает кодированный ключ PKCS # 1 в строку битов (тег 0x03, и кодирование для количества неиспользуемых битов, byte-value 0x00);
  2. добавляет последовательность идентификатора алгоритма RSA (OID RSA + нулевой параметр) впереди - предварительно кодируется как константа байтового массива;
  3. и, наконец, помещает оба из те в последовательности (тег 0x30).

Библиотеки не используются. На самом деле, для createSubjectPublicKeyInfoEncoding операторы импорта даже не требуются.


import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

public class PKCS1ToSubjectPublicKeyInfo {

    private static final int SEQUENCE_TAG = 0x30;
    private static final int BIT_STRING_TAG = 0x03;
    private static final byte[] NO_UNUSED_BITS = new byte[] { 0x00 };
    private static final byte[] RSA_ALGORITHM_IDENTIFIER_SEQUENCE =
            {(byte) 0x30, (byte) 0x0d,
                    (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x01,
                    (byte) 0x05, (byte) 0x00};


    public static RSAPublicKey decodePKCS1PublicKey(byte[] pkcs1PublicKeyEncoding)
            throws NoSuchAlgorithmException, InvalidKeySpecException
    {
        byte[] subjectPublicKeyInfo2 = createSubjectPublicKeyInfoEncoding(pkcs1PublicKeyEncoding);
        KeyFactory rsaKeyFactory = KeyFactory.getInstance("RSA");
        RSAPublicKey generatePublic = (RSAPublicKey) rsaKeyFactory.generatePublic(new X509EncodedKeySpec(subjectPublicKeyInfo2));
        return generatePublic;
    }

    public static byte[] createSubjectPublicKeyInfoEncoding(byte[] pkcs1PublicKeyEncoding)
    {
        byte[] subjectPublicKeyBitString = createDEREncoding(BIT_STRING_TAG, concat(NO_UNUSED_BITS, pkcs1PublicKeyEncoding));
        byte[] subjectPublicKeyInfoValue = concat(RSA_ALGORITHM_IDENTIFIER_SEQUENCE, subjectPublicKeyBitString);
        byte[] subjectPublicKeyInfoSequence = createDEREncoding(SEQUENCE_TAG, subjectPublicKeyInfoValue);

        return subjectPublicKeyInfoSequence;
    }

    private static byte[] concat(byte[] ... bas)
    {
        int len = 0;
        for (int i = 0; i < bas.length; i++)
        {
            len += bas[i].length;
        }

        byte[] buf = new byte[len];
        int off = 0;
        for (int i = 0; i < bas.length; i++)
        {
            System.arraycopy(bas[i], 0, buf, off, bas[i].length);
            off += bas[i].length;
        }

        return buf;
    }

    private static byte[] createDEREncoding(int tag, byte[] value)
    {
        if (tag < 0 || tag >= 0xFF)
        {
            throw new IllegalArgumentException("Currently only single byte tags supported");
        }

        byte[] lengthEncoding = createDERLengthEncoding(value.length);

        int size = 1 + lengthEncoding.length + value.length;
        byte[] derEncodingBuf = new byte[size];

        int off = 0;
        derEncodingBuf[off++] = (byte) tag;
        System.arraycopy(lengthEncoding, 0, derEncodingBuf, off, lengthEncoding.length);
        off += lengthEncoding.length;
        System.arraycopy(value, 0, derEncodingBuf, off, value.length);

        return derEncodingBuf;
    }   

    private static byte[] createDERLengthEncoding(int size)
    {
        if (size <= 0x7F)
        {
            // single byte length encoding
            return new byte[] { (byte) size };
        }
        else if (size <= 0xFF)
        {
            // double byte length encoding
            return new byte[] { (byte) 0x81, (byte) size };
        }
        else if (size <= 0xFFFF)
        {
            // triple byte length encoding
            return new byte[] { (byte) 0x82, (byte) (size >> Byte.SIZE), (byte) size };
        }

        throw new IllegalArgumentException("size too large, only up to 64KiB length encoding supported: " + size);
    }

    public static void main(String[] args) throws Exception
    {
        // some weird 617 bit key, which is way too small and not a multiple of 8
        byte[] pkcs1PublicKeyEncoding = Base64.getDecoder().decode("MFUCTgF/uLsPBS13Gy7C3dPpiDF6SYCLUyyl6CFqPtZT1h5bwKR9EDFLQjG/kMiwkRMcmEeaLKe5qdj9W/FfFitwRAm/8F53pQw2UETKQI2b2wIDAQAB");
        RSAPublicKey generatePublic = decodePKCS1PublicKey(pkcs1PublicKeyEncoding);
        System.out.println(generatePublic);
    }
}

Примечания:

  • NoSuchAlgorithmException, вероятно, следует отловить и поместить в RuntimeException;
  • закрытый метод createDERLengthEncoding вероятно, не следует принимать отрицательные размеры.
  • Большие ключи не были проверены, пожалуйста, проверьте createDERLengthEncoding для них - я предполагаю, что это работает, но лучше быть в безопасности, чем потом сожалеть.
0
ответ дан Maarten Bodewes 17 January 2019 в 14:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: