
com.sun.messaging.ums.service.SecuredSid Maven / Gradle / Ivy
The newest version!
/*
* Copyright (c) 2000, 2020 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2022 Contributors to Eclipse Foundation. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
package com.sun.messaging.ums.service;
import com.sun.messaging.jmq.util.BASE64Decoder;
import com.sun.messaging.jmq.util.BASE64Encoder;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.util.UUID;
import java.util.logging.Logger;
import jakarta.jms.JMSException;
/**
*
* @author chiaming
*/
public class SecuredSid {
private PrivateKey privateKey = null;
private PublicKey publicKey = null;
private Signature signer = null;
private Signature verifier = null;
private SecureRandom srandom = null;
private long sequence = 0;
private static BASE64Encoder encoder = null;
private static BASE64Decoder decoder = null;
private Logger logger = UMSServiceImpl.logger;
private static final String UTF8 = "UTF-8";
static {
encoder = new BASE64Encoder();
decoder = new BASE64Decoder();
}
public SecuredSid() throws JMSException {
try {
init();
} catch (Exception e) {
JMSException jmse = new JMSException(e.getMessage());
jmse.setLinkedException(e);
throw jmse;
}
}
private void init() throws NoSuchAlgorithmException, InvalidKeyException {
srandom = SecureRandom.getInstance("SHA1PRNG");
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA");
keyGen.initialize(1024, srandom);
KeyPair pair = keyGen.generateKeyPair();
// my private key to sign sid
privateKey = pair.getPrivate();
// my pub key to verify sid signature
publicKey = pair.getPublic();
signer = Signature.getInstance("SHA1withDSA");
verifier = Signature.getInstance("SHA1withDSA");
// init signature object -- i am ready to sign
signer.initSign(privateKey);
verifier.initVerify(this.publicKey);
}
/**
* sid = sequence + "-" + (signature of sequence)
*/
public synchronized String nextSid() throws JMSException {
String sid = null;
try {
// 1. generate a secure random - 20 bytes
// byte[] bytes = new byte[20];
// this.srandom.nextBytes(bytes);
if (this.sequence == Long.MAX_VALUE) {
this.sequence = 0;
}
this.sequence++;
// unique string in my domain
String prefix = String.valueOf(sequence);
// byte[] data = prefix.getBytes(UTF8);
// This makes the original string hard to guess
byte[] data = UUID.randomUUID().toString().getBytes(UTF8);
// update what to sign
signer.update(data);
// sign data -- a secured string
byte[] signature = this.signer.sign();
// encode to base64
String sigstr = encoder.encode(signature);
// use signature hash
int hash = sigstr.hashCode();
byte[] scode = Integer.toString(hash).getBytes(UTF8);
sigstr = encoder.encode(scode);
// end hash
// compose sid -- the sid is unique and secure!
sid = prefix + "-" + sigstr;
} catch (Exception e) {
JMSException jmse = new JMSException(e.getMessage());
jmse.setLinkedException(e);
throw jmse;
}
if (UMSServiceImpl.debug) {
logger.info("**** sid =" + sid + ", size=" + sid.length());
}
return sid;
}
public synchronized void verifySid(String sid) throws JMSException {
try {
// get sequence index
int index = sid.indexOf('-');
// get sequence
String seq = sid.substring(0, index);
index++;
// get signature string - base 64
String sigstr = sid.substring(index);
if (UMSServiceImpl.debug) {
logger.info("*** verifying sid, seq=" + seq + ",sig=" + sigstr + ", len=" + sigstr.length());
}
// get sequence bytes
byte[] data = seq.getBytes(UTF8);
// update what to verify
this.verifier.update(data, 0, data.length);
// decode signature from base64 to byte[]
byte[] signature = decoder.decodeBuffer(sigstr);
// verify signature
boolean isvalid = this.verifier.verify(signature, 0, signature.length);
if (isvalid == false) {
throw new SecurityException("Invalid sid., sid = " + sid);
}
if (UMSServiceImpl.debug) {
logger.info("*** sid is verified:" + isvalid + ", seq=" + seq + ",sig=" + sigstr);
}
// return isvalid;
} catch (Exception e) {
e.printStackTrace();
JMSException jmse = new JMSException(e.getMessage());
jmse.setLinkedException(e);
throw jmse;
}
}
public static String decode(String encodedString) throws JMSException {
try {
byte[] data = decoder.decodeBuffer(encodedString);
String plain = new String(data, UTF8);
return plain;
} catch (IOException e) {
JMSException jmse = new JMSException(e.getMessage());
jmse.setLinkedException(e);
throw jmse;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy