2

RSA と AES アルゴリズムのハイブリッドを使用する j2me アプリを開発しています。RSA キーは安全なキー交換の目的で使用され、AES はメッセージの暗号化に使用されます。アプリケーションは、RSA キーを生成してモバイル デバイス上の安全な場所に保存/書き込み、必要に応じてデバイスから読み取る必要があります。以下のコード (Michael Juntao 著「enterprise j2me」より) を使用してキーを生成しました。

public void generateRSAKeyPair () throws Exception {
SecureRandom sr = new SecureRandom();
BigInteger pubExp = new BigInteger("10001", 16);
RSAKeyGenerationParameters RSAKeyGenPara =
new RSAKeyGenerationParameters(pubExp, sr, 1024, 80);
RSAKeyPairGenerator RSAKeyPairGen = new RSAKeyPairGenerator();
RSAKeyPairGen.init(RSAKeyGenPara);
AsymmetricCipherKeyPair keyPair = RSAKeyPairGen.generateKeyPair();
RSAprivKey = (RSAPrivateCrtKeyParameters) keyPair.getPrivate();
RSApubKey = (RSAKeyParameters) keyPair.getPublic();
}

同書では、キーの書き込みに次のコードが使用されています。ただし、ここで使用されている FileOutputStream () クラスは CLDC ではサポートされていません (CDC と J2SE でのみサポートされています)。

BigInteger mod = RSAprivKey.getModulus();

out = new FileOutputStream(outdir + "RSAmod.dat");

out.write(mod.toByteArray());

out.flush(); out.close();



BigInteger privExp = RSAprivKey.getExponent();

out = new FileOutputStream(outdir + "RSAprivExp.dat");

out.write(privExp.toByteArray());

out.flush(); out.close();



pubExp = RSAprivKey.getPublicExponent();

if ( !pubExp.equals(new BigInteger("10001", 16)) )

throw new Exception("wrong public exponent");

out = new FileOutputStream(outdir + "RSApubExp.dat");

out.write(pubExp.toByteArray());

out.flush(); out.close();



BigInteger dp = RSAprivKey.getDP();

out = new FileOutputStream(outdir + "RSAdp.dat");

out.write(dp.toByteArray());

out.flush(); out.close();



BigInteger dq = RSAprivKey.getDQ();

out = new FileOutputStream(outdir + "RSAdq.dat");

out.write(dq.toByteArray());

out.flush(); out.close();



BigInteger p = RSAprivKey.getP();

out = new FileOutputStream(outdir + "RSAp.dat");

out.write(p.toByteArray());

out.flush(); out.close();



BigInteger q = RSAprivKey.getQ();

out = new FileOutputStream(outdir + "RSAq.dat");

out.write(q.toByteArray());

out.flush(); out.close();



BigInteger qInv = RSAprivKey.getQInv();

out = new FileOutputStream(outdir + "RSAqInv.dat");

out.write(qInv.toByteArray());

out.flush(); out.close();

RSA キーの書き込みと読み取りに最適な方法を教えてください。

4

1 に答える 1

0

キーの保存に RecordStore (RMS) を使用しました。レコードストアには、文字列、バイト、および整数の 3 つのデータ型を格納できます。ただし、RSA キーのコンポーネントは BigInteger データ型です。したがって、次のように、各主要コンポーネントの「文字列」表現/同等のものを取得しました。

//method for serializing the key components 
public void SerializeRSAKeyPair()
{

BigInteger mod = RSAprivKey.getModulus();
String mods = mod.toString();// converts to String representation

BigInteger privExp = RSAprivKey.getExponent();  
String privExps = privExp.toString(); // converts to String representation

BigInteger pubExp = RSAprivKey.getPublicExponent();
String pubExps = pubExp.toString();//..same

BigInteger dp = RSAprivKey.getDP();
String dps = dp.toString();

BigInteger dq = RSAprivKey.getDQ();
String dqs = dq.toString();

BigInteger p = RSAprivKey.getP();
String ps = p.toString();

BigInteger q = RSAprivKey.getQ();
String qs = q.toString();

BigInteger qInv = RSAprivKey.getQInv();
String qInvs = qInv.toString();

String [] RSAstrings = {mods, privExps,pubExps,dps,dqs, ps,qs,qInvs};
// all combined to a String array

writeStream(strings);
}

//Write the String array RSAKeyPairStore Recordstore

public void writeStream(String[] sData)

{

try
{
// Write data into an internal byte array
ByteArrayOutputStream strmBytes =
new ByteArrayOutputStream();
// Write Java data types into the above byte array
DataOutputStream strmDataType =
new DataOutputStream(strmBytes);
byte[] record;
for (int i = 0; i < sData.length; i++)
{
// Write Java String data
strmDataType.writeUTF(sData[i]);

// Clear any buffered data
strmDataType.flush();
// Get stream data into byte array and write record
record = strmBytes.toByteArray();
RSAKeyPairStore.addRecord(record, 0, record.length);
strmBytes.reset();
}
strmBytes.close();
strmDataType.close();
}
catch (Exception e)
{
db(e.toString());
}
}
private void db(String str)
{
System.err.println("Msg: " + str);
}



// To read the keys create separate methods for reading Public Keys and private keys     
//the record store using streams.


public void readRSApublic()
{

try
{

byte[] recData = new byte[100];

ByteArrayInputStream strmBytes =
new ByteArrayInputStream(recData);
// Read data from the above byte array
DataInputStream strmDataType =
new DataInputStream(strmBytes);

// since only the modulus and public exponents are required for computing RSA Public   keys, 
//we read record 1 and 3 as follows
RSAKeyPairStore.getRecord(1, recData, 0);
String mod = strmDataType.readUTF();
//System.out.println ("mod = " + mod);// use this to confirm that its equal to the         BigInteger/equivalent below
BigInteger RSAmod = new BigInteger(mod);
//System.out.println ("RSAmod = " + RSAmod); 
//use this confirm its equal to the      string equivalent above
strmBytes.reset();

RSAKeyPairStore.getRecord(3, recData, 0);
String pubExp = strmDataType.readUTF();
//System.out.println ("pubExp = " + pubExp);     
BigInteger RSApubExp = new BigInteger(pubExp);
//System.out.println ("RSApubExp = " + RSApubExp);
strmBytes.reset();

//then reconstruct the public key from the retrieved records
newRSApubKey = new RSAKeyParameters(false, RSAmod, RSApubExp);

// then use the key for the purpose you want e.g for encryption of data

strmBytes.close();
strmDataType.close();
}
catch (Exception e)
{
db(e.toString());
}
}

// when you need the private key, do the same; Retrieve (as strings)all the components     that makes up the private key namely; and then convert them to  BigInteger      equivalents  and then reconstruct as above 

public void readRSAprivate()
{

try
{

byte[] recData = new byte[500];

ByteArrayInputStream strmBytes =
new ByteArrayInputStream(recData);
// Read Java data types from the above byte array
DataInputStream strmDataType =
new DataInputStream(strmBytes);



RSAKeyPairStore.getRecord(1, recData, 0);
String mod = strmDataType.readUTF();
//System.out.println ("mod = " + mod);
BigInteger RSAmod = new BigInteger(mod);

strmBytes.reset();


RSAKeyPairStore.getRecord(2, recData, 0);
String privExp = strmDataType.readUTF();
//System.out.println ("privExp = " + privExp);
BigInteger RSAprivExp = new BigInteger(privExp);
//System.out.println ("RSAprivExp = " + RSAprivExp);
strmBytes.reset();

RSAKeyPairStore.getRecord(3, recData, 0);
String pubExp = strmDataType.readUTF();
BigInteger RSApubExp = new BigInteger(pubExp);
strmBytes.reset();

RSAKeyPairStore.getRecord(4, recData, 0);
String dps = strmDataType.readUTF();
BigInteger RSAdp = new BigInteger(dps);
strmBytes.reset();

RSAKeyPairStore.getRecord(5, recData, 0);
String dqs = strmDataType.readUTF();
BigInteger RSAdq = new BigInteger(dqs);
strmBytes.reset();

RSAKeyPairStore.getRecord(6, recData, 0);
String p = strmDataType.readUTF();
BigInteger RSAp = new BigInteger(p);
strmBytes.reset();

RSAKeyPairStore.getRecord(7, recData, 0);
String q = strmDataType.readUTF();
BigInteger RSAq = new BigInteger(q);
strmBytes.reset();

RSAKeyPairStore.getRecord(8, recData, 0);
String qInv = strmDataType.readUTF();
BigInteger RSAqInv = new BigInteger(qInv);
strmBytes.reset();   

// then use the key for the purpose you want e.g for Signing
newRSAprivKey = new RSAPrivateCrtKeyParameters(RSAmod, RSAprivExp, RSApubExp, RSAp,

RSAq, RSAdp, RSAdq, RSAqInv);

strmBytes.close();
strmDataType.close();
}
catch (Exception e)
{
db(e.toString());
}
}
于 2014-03-20T14:19:16.847 に答える