Charles ForsythPK/SK instances for RSA keysa2faff312 years agoHistory
140 lines · 4.0 KB · Java
RawDownload
package plan9.auth; import java.math.BigInteger;import java.security.*;import java.security.interfaces.*;import java.security.spec.*;import java.nio.*;import java.nio.channels.*;import java.io.IOException;import javax.crypto.Cipher;import java.io.*;import java.util.Date; import java.util.Arrays;import java.util.ArrayList; import plan9.lib.Attr;import plan9.lib.Attrs;import plan9.lib.Key;import plan9.lib.Keys;import plan9.lib.Packer;import plan9.lib.Strings;import plan9.lib.Base16;import plan9.lib.Encoding;import plan9.lib.Base64;import plan9.lib.Strings; import plan9.LogFactory;import plan9.Log; import static plan9.auth.Pki.need;import static plan9.auth.Aids.b64;import static plan9.auth.Aids.b16;import static plan9.auth.Aids.s2big64;import static plan9.auth.Aids.s2big16;import static plan9.auth.Aids.trim0; public class RsaSK implements SK { 	static final Log log = LogFactory.logger(RsaSK.class); 	BigInteger n;	BigInteger ek;	BigInteger dk;	BigInteger p;	BigInteger q;	BigInteger kp;	BigInteger kq;	BigInteger c12; 	public RsaSK(int length) throws CryptoError {		try{			// can't easily make kpg static because key-pair lengths might vary			KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");			kpg.initialize(length);			KeyPair kp = kpg.generateKeyPair();			extract((RSAPrivateKey)kp.getPrivate());		}catch(NoSuchAlgorithmException e){			throw new CryptoError("no KeyPairGenerator for RSA: "+e.getMessage());		}catch(InvalidParameterException e){			throw new CryptoError("unsupported length for RSA: "+length);		}	}	public RsaSK(RSAPrivateKey sk){		extract(sk);	}	public RsaSK(Key k) throws InvalidKey {		n = s2big16(need(k, "n"));		ek = s2big16(need(k, "ek"));		dk = s2big16(need(k, "!dk"));		p = s2big16(need(k, "!p"));		q = s2big16(need(k, "!q"));		kp = s2big16(need(k, "!kp"));		kq = s2big16(need(k, "!kq"));		c12 = s2big16(need(k, "!c2"));	}	public String toString(){		// size ek !dk n !p !q !kp !kq !c2		return String.format("size=%d ek=%s !dk=%s n=%s !p=%s !q=%s !kp=%s !kq=%s !c2=%s",			this.n.bitLength(), b16(this.ek), b16(this.dk),			b16(this.n), b16(this.p), b16(this.q),			b16(this.kp), b16(this.kq), b16(this.c12));	} 	public final PKsig sign(BigInteger digest){		BigInteger val = rsadecrypt(digest);System.out.format("digest=%s%nval=%s%n", digest, val);System.out.format("val'=%s%n", b16(val.toByteArray()));		PKsig sig = new PKsig("rsa");		sig.add("val", trim0(val.toByteArray()));		return sig;	} 	public final PK pk(){		return new RsaPK(n, ek);	} 	// extra operation not in SK/PK	public final BigInteger rsadecrypt(BigInteger m){		BigInteger v1, v2;		v1 = m.mod(p);		v2 = m.mod(q);		v1 = v1.modPow(kp, p);		v2 = v2.modPow(kq, q);		// out = v1 + p*((v2-v1)*c2 mod q)		return v2.subtract(v1).multiply(c12).mod(q).multiply(p).add(v1);	} 	// for reference: unused	protected RSAPrivateKey cvt() throws InvalidKey {		// we can't actually use Java's operations here because it imposes PKCS#1, so we do the calculation ourselves		try{			KeyFactory keyfactory = KeyFactory.getInstance("RSA");			RSAPrivateKey jsk = (RSAPrivateKey)keyfactory.generatePrivate(new RSAPrivateCrtKeySpec(n, ek, dk, q, p, kq, kp, c12));			if(log.debugging())				log.debug("java sk = %s", jsk);			return jsk;		}catch(InvalidKeySpecException ex){			throw new InvalidKey("bad key spec: "+ex.getMessage());		}catch(NoSuchAlgorithmException e){			throw new InvalidKey("RSA not implemented: "+e.getMessage());		}	} 	// extract the components from a Java-generated key	private void extract(RSAPrivateKey sk){		// mind your p's and q's: libsec's p is java's q!  (Java follows PKCS#1 in reversing their roles)		// to use Java's RSA implementation directly, we reverse p and q, and kp and kq		// apparently we can safely do these casts		RSAPrivateCrtKey ck = (RSAPrivateCrtKey)sk;		n = ck.getModulus();		ek = ck.getPublicExponent();		dk = ck.getPrivateExponent();		p = ck.getPrimeQ();		q = ck.getPrimeP();		kp = ck.getPrimeExponentQ();		kq = ck.getPrimeExponentP();		c12 = ck.getCrtCoefficient();	}}