try {
KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA");
// create custom RSA factories
SignatureFactory factory = new RSASignatureFactory();
SignatureCodec codec = new RSASignatureCodec();
// replace default signature factories
ChannelClientConfiguration clientConfig = PeerBuilder.createDefaultChannelClientConfiguration();
clientConfig.signatureFactory(factory);
ChannelServerConfiguration serverConfig = PeerBuilder.createDefaultChannelServerConfiguration();
serverConfig.signatureFactory(factory);
KeyPair keyPairPeer1 = gen.generateKeyPair();
p1 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash(1)).ports(4834).keyPair(keyPairPeer1)
.channelClientConfiguration(clientConfig)
.channelServerConfiguration(serverConfig).start()).start();
KeyPair keyPairPeer2 = gen.generateKeyPair();
p2 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash(2)).masterPeer(p1.peer()).keyPair(keyPairPeer2)
.channelClientConfiguration(clientConfig)
.channelServerConfiguration(serverConfig).start()).start();
p2.peer().bootstrap().peerAddress(p1.peerAddress()).start().awaitUninterruptibly();
p1.peer().bootstrap().peerAddress(p2.peerAddress()).start().awaitUninterruptibly();
KeyPair keyPairOld = gen.generateKeyPair();
KeyPair keyPairNew = gen.generateKeyPair();
Number160 lKey = Number160.createHash("location");
Number160 dKey = Number160.createHash("domain");
Number160 cKey = Number160.createHash("content");
Number160 vKey = Number160.createHash("version");
Number160 bKey = Number160.ZERO;
int ttl = 10;
String testData = "data";
Data data = new Data(testData).protectEntryNow(keyPairOld, factory);
data.ttlSeconds(ttl).addBasedOn(bKey);
// initial put of some test data
FuturePut futurePut = p1.put(lKey).domainKey(dKey).data(cKey, data).versionKey(vKey)
.keyPair(keyPairOld).start();
futurePut.awaitUninterruptibly();
Assert.assertTrue(futurePut.isSuccess());
// create signature with old key pair having the data object
byte[] signature1 = factory.sign(keyPairOld.getPrivate(), data.buffer()).encode();
// decrypt signature to get hash of the object
Cipher rsa = Cipher.getInstance("RSA");
rsa.init(Cipher.DECRYPT_MODE, keyPairOld.getPublic());
byte[] hash = rsa.doFinal(signature1);
// encrypt hash with new key pair to get the new signature (without
// having the data object)
rsa = Cipher.getInstance("RSA");
rsa.init(Cipher.ENCRYPT_MODE, keyPairNew.getPrivate());
byte[] signatureNew = rsa.doFinal(hash);
// verify old content protection keys
Data retData = p1.get(lKey).domainKey(dKey).contentKey(cKey).versionKey(vKey).start()
.awaitUninterruptibly().data();
Assert.assertTrue(retData.verify(keyPairOld.getPublic(), factory));
// create a dummy data object for changing the content protection key
// through a put meta
Data dummyData = new Data();
dummyData.addBasedOn(bKey).ttlSeconds(ttl);
// assign the reused hash from signature (don't forget to set the
// signedflag)
dummyData.signature(codec.decode(signatureNew)).signed(true).duplicateMeta();
// change content protection key through a put meta
FuturePut futurePutMeta = p1.put(lKey).domainKey(dKey).putMeta().data(cKey, dummyData)
.versionKey(vKey).keyPair(keyPairOld).start();
futurePutMeta.awaitUninterruptibly();
Assert.assertTrue(futurePutMeta.isSuccess());