All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.siisise.security.key.RSAPublicKey Maven / Gradle / Ivy

/*
 * Copyright 2022-2023 okome.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.siisise.security.key;

import java.math.BigInteger;
import java.util.LinkedHashMap;
import net.siisise.bind.format.TypeFormat;
import net.siisise.ietf.pkcs.asn1.AlgorithmIdentifier;
import net.siisise.ietf.pkcs1.PKCS1;
import net.siisise.iso.asn1.tag.BITSTRING;
import net.siisise.iso.asn1.tag.INTEGER;
import net.siisise.iso.asn1.tag.NULL;
import net.siisise.iso.asn1.tag.OBJECTIDENTIFIER;
import net.siisise.iso.asn1.tag.OCTETSTRING;
import net.siisise.iso.asn1.tag.SEQUENCE;

/**
 * RFC 8017 PKCS #1
 * RFC 4716 SSH Public Key
 */
public class RSAPublicKey implements java.security.interfaces.RSAPublicKey {

    private static final long serialVersionUID = 1L;
    /**
     * n modulus
     */
    private final BigInteger modulus;
    /**
     * e 公開指数
     */
    private final BigInteger publicExponent;

    /**
     * nとeで公開鍵をつくる
     * @param n modulus
     * @param e publicExponent
     */
    public RSAPublicKey(BigInteger n, BigInteger e) {
        modulus = n;
        publicExponent = e;
    }

    /**
     * 公開指数.
     * @return public exponent
     */
    @Override
    public BigInteger getPublicExponent() {
        return publicExponent;
    }

    /**
     * n modulus を返す
     * @return n modulus
     */
    @Override
    public BigInteger getModulus() {
        return modulus;
    }

    /**
     * RSA
     * @return "RSA"
     */
    @Override
    public String getAlgorithm() {
        return "RSA";
    }

    public static enum Format {
        PKCS1, // RFC 8017 A.1.1.
        PKCS8,
//        X509,
//        SSH2, // RFC 4716 4253
    }
    
    /**
     * エンコードタイプ
     * @return 
     */
    @Override
    public String getFormat() {
        return "X.509";
    }
    
    @Override
    public byte[] getEncoded() {
        return getPKCS1Encoded();
    }

    /**
     * RSA Public Key Syntax.
     * RFC 8017 A.1.1. 
     * @return RFC 8017 A.1.1.形式のASN.1 DER
     */
    public byte[] getPKCS1Encoded() {
        return getPKCS1ASN1().encodeAll();
    }

    public SEQUENCE getPKCS1ASN1() {
/*      // rebind 任せでもいい
        return (SEQUENCE)rebind(new ASN1Convert());
/*/
        SEQUENCE pub = new SEQUENCE();
        pub.add(modulus); // n
        pub.add(publicExponent); // e
        return pub;
//*/
    }
    
    /**
     * ASN.1 その他適度な型に変換する.
     * modulus と publicExponent のみ
     * @param  出力型
     * @param format 出力先、書式
     * @return 出力
     */
    public  T rebind(TypeFormat format) {
        LinkedHashMap rsaPublicKey = new LinkedHashMap();
        rsaPublicKey.put("modulus", modulus); // n
        rsaPublicKey.put("publicExponent", publicExponent); // e
        return format.mapFormat(rsaPublicKey);
    }
    
    /**
     * PKCS #8 PUBLIC KEY
     * bit string のパターン
     * @return PKCS #8 DER
     */
    public byte[] getPKCS8Encoded() {
        return getPKCS8ASN1().encodeAll();
    }

    public SEQUENCE getPKCS8ASN1() {
        SEQUENCE s = new SEQUENCE();
        AlgorithmIdentifier aid = new AlgorithmIdentifier("1.2.840.113549.1.1.1");
        s.add(aid.encodeASN1());
        s.add(new BITSTRING(getPKCS1Encoded()));
        return s;
    }

    /**
     * X.509 証明書形式が一般的かな
     * OCTET STRING のパターン.
     * @deprecated まだ
     * @return 
     */
    @Deprecated
    public byte[] getRawEncoded() {
        SEQUENCE s = new SEQUENCE();
        s.add(new INTEGER(0));
        SEQUENCE v = new SEQUENCE();
        v.add(new OBJECTIDENTIFIER("")); // ToDo: 不明
        v.add(new NULL());
        s.add(v);
        s.add(new OCTETSTRING(getPKCS1Encoded()));
        return s.encodeAll();
    }
        
    /**
     * RSA Encryption Primitive
     * 5.1.1. RSAEP
     * 暗号化.
     * 秘密鍵の RSADP と対
     * @param m メッセージ 0 から n-1の間の整数
     * @return 暗号 c 0 から n-1 の間の整数
     * @see RSAMiniPrivateKey#rsadp(java.math.BigInteger) 
     */
    public BigInteger rsaep(BigInteger m) {
        if ( m.compareTo(BigInteger.ZERO) < 0 || m.compareTo(modulus) >= 0 ) {
            throw new SecurityException("message representative out of range");
        }
        return m.modPow(publicExponent, modulus);
    }

    /**
     * 暗号化.
     * 秘密鍵の RSADP と対
     * @param m メッセージ 0 から n-1の間の整数 のバイナリ
     * @return 暗号 c 0 から n-1 の間の整数
     */
    public BigInteger rsaep(byte[] m) {
        return rsaep(PKCS1.OS2IP(m));
    }
    
    /**
     * 入出力をbyte array にしたもの
     * @param m メッセージ 0 から n-1の間の整数
     * @param l 戻りオクテット長
     * @return 
     */
    public byte[] rsaep(byte[] m, int l) {
        return PKCS1.I2OSP(rsaep(PKCS1.OS2IP(m)), l);
    }

    /**
     * 署名検証.
     * 5.2.2. RSAVP1
     * @param s 署名
     * @return 原文(ハッシュ)
     */
    public BigInteger rsavp1(BigInteger s) {
        if ( s.compareTo(BigInteger.ZERO) < 0 || s.compareTo(modulus) >= 0 ) {
            throw new SecurityException("signature representative out of range");
        }
        return s.modPow(publicExponent, modulus);
    }
    
    public byte[] rsavp1(byte[] s, int l) {
        return PKCS1.I2OSP( rsavp1(PKCS1.OS2IP(s)), l);
    }
    
    /**
     * 7.1.1. Encryption Opeation
     * mLen <= k - 2hLen - 2
     * @param m key length
     * @param label 2^61 - 1 octets for SHA-1
     * @return C 長さkの暗号化テキスト
     */
/*
    BigInteger rsaes_oaep_encrypt(byte[] m, byte[] label) {
        // ラベル長エラーは省略する.
        // ToDo: メッセージ長チェックが必要
        MessageDigest md = new SHA1();
//        if (m.length > )
        
        
    }
*/
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy